ClockWise or Counterclockwise

Started by
7 comments, last by erissian 16 years, 11 months ago
Hi everyone, I think I need help. Probably this question should be on "for beginner", but I think I will get more answer here. Here's my problem: I have a character that move and rotate based on analog stick on gamepad. If I press my analog stick to the left then the character should be rotate on 270 degrees ( or 1.5 PI ), and if I press my analog stick to forward, it will rotate to 0 ( or 0 PI ) degrees. So, what I'd like to accomplished here is make the character has more smoother rotation. Not making sudden rotation 270 to 0 (if i press left and then forward). I want to interpolate this two rotation point. But I'm having difficulties to decide which direction to rotate. Should the rotate clockwise, or counter clockwise. Rotate 270-0 is better with 90 degrees(clockwise) than 270 degrees(counter clockwise). Can anybody help me here? the function interface should be something like this:

bool IsRotateClockWise( float fCurRotate, float fNewRotate )
{
  // the code goes here....
}

Thanks before.
Advertisement
Hi,
If you look from the end user point of view, it has no impact on gameplay.
As to coding, I would suggest you to stick with the convention you prefer(clockwise or counterclockwise).

As to me, I am using counterclockwise convention everywhere because:
- it is more coherent with all my 3D code (triangles declared Counterclockwise).
- I am more comfortable with (because of my math background).

Ghostly yours,
Red.
Ghostly yours,Red.
I think you misunderstood the question there, Red Ghost.

Anyway, you could spend all day coming up with elegant ways to work around the periodicity, but I found it best to keep it simple and perform a case analysis. I'll work in degrees, so I don't have to keep writing p [rolleyes]:

First, make sure that the source and destination angles are in the range 0-360. In general, this means adding ceil(abs(angle / 360.0)) * 360.0 for negative values, then taking the floating modulus.

Now there are four cases to consider.

1. (source < dest) && (dest - source < 180) : Clockwise
2. (dest < source) && (source - dest < 180) : Anticlockwise
3. (source < dest) && (dest - source > 180) : Anticlockwise
4. (dest < source) && (source - dest > 180) : Clockwise

That's right, right? You'll probably want to throw some weak inequalities in there to cover the degenerate cases.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Considering that I'm a sucker for cool tricks and vector math, I'll present another approach that's Kinda Neat™.

If you take the cross product between the source vector and the destination vector, the direction of the resulting vector can be used to determine whether to move clockwise or counter-clockwise. Since you're working in 2D, all the math simplifies down to:
float direction = cos(fCurRotate)*sin(fNewRotate) - cos(fNewRotate)*sin(fCurRotate);if(direction > 0.0f)   doCounterClockwise();else   doClockwise;

The angular delta that you need to rotate can either be determined using an additional dot product, or you can use some other geometric logic.
Quote:Original post by Red Ghost
Hi,
If you look from the end user point of view, it has no impact on gameplay.
As to coding, I would suggest you to stick with the convention you prefer(clockwise or counterclockwise).

As to me, I am using counterclockwise convention everywhere because:
- it is more coherent with all my 3D code (triangles declared Counterclockwise).
- I am more comfortable with (because of my math background).

Ghostly yours,
Red.

RTFQ [grin]

Well, if you ever need advice on hidden surface removal, you got it. =b
Quit screwin' around! - Brock Samson
@All
Thanks for the replies.
I found a way, and it seems right.
bool IsRotateClockWise( float fCurRotate, float fNewRotate ){  float fR1 = fCurRotate - fNewRotate;  float fR2 = fNewRotate - fCurRotate;  if( fR1 < 0.f )    fR1 += TWO_PI;  if( fR2 < 0.f )    fR2 += TWO_PI;  return fR2 < fR1;}


Thanks again guys.
I stuck this in the other thread too, but I just want to put in my two cents:

Given an orientation and a destination, this function gives the shortest angle in radians:
float shortestArc(float a, float b){    if (fabs(b-a) < M_PI)        return b-a;    if (b>a)        return b-a-M_PI*2.0f;    return b-a+M_PI*2.0f;}
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
Quote:Original post by erissian
Given an orientation and a destination, this function gives the shortest angle in radians
Could you tell us for which parameter ranges this is valid?

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Quote:Original post by TheAdmiral
Quote:Original post by erissian
Given an orientation and a destination, this function gives the shortest angle in radians
Could you tell us for which parameter ranges this is valid?

Admiral


Fair question; if I recall correctly, the assumption is that both arguments are in the range [0,2Π], and that adjustment was in a separate function.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)

This topic is closed to new replies.

Advertisement