stick rotation

Started by
3 comments, last by TheAdmiral 17 years ago
Hi I want to test if an analogue stick on a control pad has done a full rotation (i.e. from the "up" position all the way round clockwise through "left","down","right" and back to "up"). I can sample the inupt over time and convert it to an angle but how do I test if the stick has made a full 360 degree turn? thanks
Advertisement
When the angle goes from one spot, all the way around in a 360degree circle. Then it has made a full 360 turn.
So basically, I'd just consider that there are 8 possible sequences which represent circles:
left, up, right, down
up, right, down, up
right, down, left, up
down, left, up, right

and the reverse of those


so... just keep track of what directions the stick moves in. If the last 4 positions match any of thoses lists, then it counts as a circle.
Might even want to put some check in there where they have to occur within 1 second of each other...
What I'd do is separate the analog stick into 9 areas:

Center
TopLeft
Top
TopRight
Right
BottomRight
Bottom
BottomLeft
Left

Then every frame when you poll the stick, identify which of the 9 areas the stick is currently in. Then I'd have a rolling list of the last N areas that I was in which only gets modified when the current area is different than the last. The size of the list depends on the complexity of the moves. For a full circle, you may want to have 8 or 9 ( 9 so that you repeat the Top area).

One issue you may have is that the value reported by analog sticks can wiggle even when the stick is static, so you may want to expand the current area you're in when doing the test and checking to see if the user has moved. Hope this makes sense.

In a little more detail:

First, decide which starting and ending points are allowed and what qualifies as a full circle, as these will determine how much information you need to keep track of. For example, if a circle must start and end at 'up', then you can get away with remembering only three values. However, if arbitrary positions are allowed, you'd be better of with ten or more. The idea is to split the phase space into n regular segments and maintain a cyclic list describing the last n (or n+1) segments visited.

Each frame, poll the stick and determine which segment it's in, by means of atan2 or similar. If the current segment is different to last frame's, then add this segment to the cyclic list. In order to prevent small circles from counting, you may want to include a rogue 'dead-zone' value that is added to the list whenever the stick is too close to its central position.

Now in order to determine when a circle has been made, you only need to check that the cyclic list contains no duplicates (and no rogue-values).

There are a couple of problems with this method:
First, this will only work if your frame-rate is sufficiently high. If we miss the stick passing through a segment, the circle won't register.
And second, the circle will trigger whenever all segments have been visited in a cyclic fashion, which isn't necessarily the same as when a full circle has been made. In particular, the worst-case scenario is a false positive after rotating through 360*(n - 1)/n degrees.

Clearly, the first problem worsens as n increases and the second as n decreases, so you'd have to play around a bit to find a suitable value. Alternatively, you could eliminate the second problem by increasing the list to hold n+1 elements and performing an extra check or two.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.

This topic is closed to new replies.

Advertisement