Unit rotation in a game
I have a unit in a game which is pointing in a particular direction; when it turns to another direction it should take the shortest turn available. The scheme starts at a particular angle, and requires a given angle to lerp (linear interpolate) towards.
For example, lerping from 10 degrees to 350 degrees should calculate a target angle of -10. Conversely lerping from 350 to 10 should calculate an end end of 370 degrees.
What algorithm can calculate these required end values?
EDIT:: There seems to be some confusion over what I need
I'm using linear interpolation to calculate angles over time. So, if I want to get from 10 to 20 then the end value needs to be 20, then I shall interpolate from 10 to 20 and turn right. However, similarly if I want to go from 20 to 10, then interpolating from 20 to 10 will go anticlockwise, this is fine too. The problem is when the turn is more than 180 in the clockwise direction, to go from 270 t开发者_如何学Co 80 (210 degrees) needs to turn clockwise, direct interpolation from 270 to 80 will go anticlockwise, I need to interpolate from 270 to 420 (360+80), which will go anticlockwise.
You need
dist = (end - start + 360) % 360;
if (dist > 180)
dist = dist - 360;
that gives you something in the range -180...180. If that is what you want.
If you want something more focused on the 'end angle', how about this:
float startAngle = something, endAngle = something;
endAngle = ((endAngle - startAngle) % 360) + startAngle;
if(endAngle < startAngle - 180) endAngle += 360;
if(endAngle > startAngle + 180) endAngle -= 360;
This brings endAngle as close to startAngle as possible in increments of 360.
Martin, I think I understand what you want. Basically, you just need to add 360 to your end position until it's greater than your start position. Then subtract 360 from that. Those are the two absolute angles that could possibly be your solution. Then your answer is merely whichever is closest.
Pseudocode / real code:
int current = 350; // where you are now
int desired = 10; // where you want to go
while( desired < current)
desired += 360;
int end = desired;
int start = desired - 360;
int delta1 = abs( end - current);
int delta2 = abs( start - current);
int answer = delta1 < delta2 ? end : current;
If you are turning towards a specific point and just want to know whether to turn clockwise or anti-clockwise during this frame, the usual way of doing it is to consider the player's direction as a vector, and take the cross-product between it and the vector spanning from the player to the point. If it is positive, turn anti-clockwise; if it's negative, turn clockwise.
精彩评论