I have a sprite, e.g a missile, heading in a certain direction (using a velocity vector). How do I figure out its how much to rotate it so that it gets drawn 'pointing' in the direction it is heading?
-
possible duplicate of How can I calculate the angle between two 2D vectors? – House Oct 15 '12 at 16:30
-
This is just calculating the angle between two vectors. The direction the sprite is currently heading, and the direction you want it to head. Though, it should make a good pointer to that question though once it's closed. – House Oct 15 '12 at 16:31
-
1@Byte56 agreed, it's calculating the angle between a vector and the x-axis. But the question is framed as an application of this calculation. A beginner trying to solve this problem might not think of it in terms of an angle between vectors. – Ken Oct 15 '12 at 16:37
-
Yep, that's why I said it will make a good pointer to the other question. It's still the same question, just asked in a different (simpler) way. You've already agreed to that. It's not a bad thing for it to be closed as a duplicate. If your motivation is to help beginners searching, you've done that by asking the question. – House Oct 15 '12 at 16:40
-
fair enough. would it be appropriate to copy the answer to the other question, if for nothing more than to provide a XNA example (and to show how the upside-down issue can be dealt with) – Ken Oct 15 '12 at 16:42
-
Well, thinking about it more. Your answer probably isn't a good fit for the other question. This one is more specific to the rotation of a sprite, and introduces the idea of using the "default" axis for one of the axis (in this case the positive x axis). So maybe it's not worth closing after all. I guess it's just worth noting that it's the same thing. We'll see what the community decides. – House Oct 15 '12 at 16:47
1 Answers
The angle you need to rotate by is the the angle your velocity vector makes with the positive x-axis.
This angle can be calculated using the inverse tan of the slope of the vector. In XNA, we use the Math.Atan2 function. Give the function the y coordinate and the x coordinate of the velocity vector (in that order). Atan2 will return an angle between +PI/2 and -PI/2. (+180 to -180 degrees) depending on the vector. Vectors below the x-axis (pointing down) have a negative angle. Vectors above the x-axis (pointing up) have positive angle.
Use this angle in your draw method to rotate the sprite.
public void UpdateSprite(GameTime gameTime, GraphicsDeviceManager graphics)
{
// Move the sprite by speed, scaled by elapsed time.
spritePosition += spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
//figure out the angle that the sprits velocity vector is making with the
//positive x-axis
//Atan2 will return an angle (in radians) from -PI to +PI
angle = (float)Math.Atan2(spriteSpeed.Y , spriteSpeed.X);
flip = SpriteEffects.None;
if (spriteSpeed.X < 0)
{ //for cases when the sprite is moving right to left, the rotation angle will be >90deg or < -90deg,
//so the sprite will be drawn upside down.
// fix this by flipping the sprite vertically
flip = SpriteEffects.FlipVertically;
}
}
public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
if(!alive) return;
spriteBatch.Draw(myTexture, spritePosition, null, Color.White, angle, spriteOrigin, 1,flip, 1);
}
In my example I used a duck sprite, which if rotated by more than PI/4 (90deg) will start to look 'upside-down'. This might not be a problem for some spites if they do not have 'correct' orientation. (e.g. a missile), but things like aeroplanes or birds might look 'wrong'. Fix this issue by flipping the sprite vertically if the sprite is moving right to left (rotation is not in range -PI/4 to PI/4).
We can check for this either by looking at the angle to see if it is greater than PI/4 or less than -PI/4, OR, equivalently, we can simply check which direction along the x-axis the sprite is moving. If it is moving right to left it will have a negative x-component, this is the way I check in the code above.

- 6,116
- 3
- 35
- 51