lawls
lawls

Reputation: 1508

Add or subtract to an angle to reach onther angle the shortest way

I have encountered some issues regarding angles. I have an angle A and another angle B, I want to animate A the shortest way so that it reaches B. The first confusion for me is that angles go from 0 to 180, and 0 to -180. Not sure what the pros of that is. Anyway, I will give a for instance:

float a = -35;
float b = 90;

For each update I want to either add 1 or subtract 1 degree from a, until it reaches b, and I want to make sure it goes the shortest way.

Here's my code, which seems to be working. But it does not seem very efficient:

b += 360;
if (b > a) {
    if (b - a < 180) {
        a += 1;
    } else {
        a -= 1;
    }
} else {
    if (a - b < 180) {
        a -= 1;
    } else {
        a += 1;
    }
}

Is there a better/easier way to do it?

Upvotes: 1

Views: 1518

Answers (1)

Tim B
Tim B

Reputation: 41168

So you want the shortest route from a to b.

Since we are looking at a difference lets subtract:

 float d = a-b;

If the value of the result is greater than 180 then we want to subtract 360.

 if (d > 180) {
    d -= 360;
 } else if (d<-180) {
    d += 360;
 }

Now d is the total distance to travel. You can compare that with 0 to see which way to go. You can also do nice things like move further the larger d is. For example to make it always move 10% of the way (note that this series will never end as it will constantly approach by smaller and smaller amounts so you need to cope with that scenario):

 a += d/10;

You also need to consider frame rate if you want a smooth animation.

If you work out tpf (time per frame) as a floating point fraction of a second.

long frameTook = lastFrame - System.currentTimeMillis();
long lastFrame = System.currentTimeMillis();
float tpf = frameTook / 1000;

You can now do a constant animation (where degreesPerFrame is the speed of animation) using:

float move = degreesPerFrame * tpf;

Check we aren't going to move past the destination, if we are just move to it.

if (move > FastMath.abs(d)) {
    a = b;
} else {
    if (d>0) {
        a+=move;
    } else {
        a-=move;
    }
}

Upvotes: 4

Related Questions