views:

106

answers:

3

Hi. I am programming a game and I have come to a very hard spot. Basically I have a circle and I have 2 angles on this circle. Angle 1 (A) is a point I want angle 2 (B) to go to. During my game every frame I need to check weither or not to increase or decrease my angle value by a certain amount (speed) to eventually reach the first angle. My question is how do I do this?

I tried doing this but I don't seem to be doing it right.

bool increase = false;

float B = [self radiansToDegrees:tankAngle];
float A = [self radiansToDegrees:tankDestinationAngle];
float newAngle = B;

if(B < A) {

    float C = B - (360 - A);
    float D = A - B;

    if(C < D) increase = false;
    else increase = true;

} else if(B > A) {

    float C = B - A;
    float D = A - (360 - B);

    if(C < D) increase = false;
    else increase = true;

}

if(increase) {
    newAngle += 1.0;
} else {
    newAngle -= 1.0;
}

if(newAngle > 360.0) {
    newAngle = 0 + (newAngle - 360.0);
} else if(newAngle < 0.0) {
    newAngle = 360 + newAngle;
}

if(newAngle == 0) newAngle = 360;

newAngle = [self degreesToRadians:newAngle];

[self setTanksProperPositionRotation:newAngle];

The basic effect I am trying to achieve is when the user makes a new point, which would be angle 1, angle 2 would move towards angle 1 choosing the fastest direction. I think I have spent around 4 hours trying to figure this out.

A: 

Basically you want to check which angle gives you the smallest arc length (L).

alt text

alt text

Nick D
Awesome thanks. Just got figure out what the first symbol in the equation means.
Thomas
@Thomas: I'm glad I could help. Do you mean the `a`? It's the angle measured in degrees. If you have the angle in radians then the type is simpler: `L = theta * r`
Nick D
This answer is useless. Since r, pi, and 180 are all constants, you are basically saying *"use whichever angle is smaller"* - which is what he's having troubles with!
BlueRaja - Danny Pflughoeft
+1  A: 

Normalize the angles between 0 and 360 degrees, and take whichever is smaller:

float normalize(float angle)
{
    while(angle < 0)
        angle += 360;
    return angle % 360;
}

//To use...
float angle1 = A - B;
float angle2 = B - A;
if(normalize(angle1) < normalize(angle2))
    //Use angle1
else
    //Use angle2
BlueRaja - Danny Pflughoeft
" Angle 1 (A) is a point I want angle 2 (B) to go to. "
Pete Kirkham
@Pete: Thank you, I missed that; corrected.
BlueRaja - Danny Pflughoeft
+1  A: 

Assuming that the current and desired are positive and less than 360:

float inc; // abs. distance from current to desired if incrementing
float dec; // abs. distance from current to desired if decrementing

if (current > desired)
{
    inc = current + 360.0f - desired; // incrementing would wrap over
    dec = current - desired;
}
else
{
    inc = desired - current;
    dec = current + 360.0f - desired; // decrementing would wrap over
}

// the expressions above are arranged so inc and dec are both +ve
// so just compare them
if (inc < dec)
    newAngle = current + step;
else 
    newAngle = current - step;
Pete Kirkham