Like if the angle it should be at is 340 and its angle is 10 it'll go the long way to turn instead of subtracting to get to 0 then going to 340. |
The simplest solution for this is to use the [perpendicular] dot product.
The perpdot product is linear algebra magic which can be used here to determine which "side" of the missile your target is on. All you need are 3 vectors:
1) The position of the missile
2) The position of the target
3) The velocity of the missile (ie: X and Y speed)
You can use these 3 points to form a triangle, with the missile position being the key angle. The tricky bit here is that the sine of that angle will be positive if the target is on the right, or negative if the target is on the left. And the sine of the angle is exactly what the perpdot product gives you!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
// Assume you have a 'Vector' or 'Point' or somesuch class, which has x and y properties:
// Linear Algebra magic!
// Once you understand how to use these functions, you will use them ALL THE
// FREAKING TIME
// returns cos(theta)*length(a)*length(b), where theta = the angle between vectors a,b
inline double dot(const Vector& a, const Vector& b)
{
return (a.x*b.x) + (a.y*b.y);
}
// returns sin(theta)*length(a)*length(b), where theta = the angle between vectors a,b
inline double perpDot(const Vector& a, const Vector& b)
{
return (a.y*b.x) - (a.x*b.y);
}
|
Again, noting that the sign of sin(theta) is all we really care about, checking to see which way we need to rotate is easy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
// our 3 points of interest:
Vector missile_pos = ...;
Vector target_pos = ...;
Vector missile_velocity = ...;
double d = perpDot( target_pos - missile_pos, missile_velocity );
if( d < 0 )
{
// rotate your missile clockwise
}
else if(d > 0)
{
// rotate your missile counter-clockwise
}
else
{
// missile is headed either directly towards or directly away from the target. Find out which:
d = dot( target_pos - missile_pos, missile_velocity );
if( d < 0 )
{
// headed directly away. Rotate either CW or CCW -- doesn't matter
}
else
; // headed directly towards -- no need to rotate.
}
|
NOTE: if you try this and your missile starts flying away from the target instead of towards, I might have gotten the sign backwards. Just flip the CW/CCW rotation around.