6
\$\begingroup\$

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?

\$\endgroup\$
6
  • \$\begingroup\$ possible duplicate of How can I calculate the angle between two 2D vectors? \$\endgroup\$
    – House
    Oct 15, 2012 at 16:30
  • \$\begingroup\$ 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. \$\endgroup\$
    – House
    Oct 15, 2012 at 16:31
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – Ken
    Oct 15, 2012 at 16:37
  • \$\begingroup\$ 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. \$\endgroup\$
    – House
    Oct 15, 2012 at 16:40
  • \$\begingroup\$ 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) \$\endgroup\$
    – Ken
    Oct 15, 2012 at 16:42

1 Answer 1

15
\$\begingroup\$

The angle you need to rotate by is the the angle your velocity vector makes with the positive x-axis.

veclocity vector

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);



    }

enter image description here

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.

enter image description here

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .