Reputation: 1508
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
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