Rotate to match a heading

OK, sorry if this is already somewhere.... I couldn't find it when I did a search.

I'm working on a 2D project where I have images moving around the screen. They have a 'heading' vector that is sort of generated randomly. I'm trying to calculate an angle of rotation based on the dot product between the heading vector and a 'straight' vector of (1.0f, 0.0f) ... I'm using this because the original image for rotation is facing to the left. (its actually a left arrow --> )

It seems like its sort of working, but not quite right. Sometimes they aren't oriented correctly, and when I put in a negative value for the heading like (0.0f, -1.0f) it rotates as if the heading were (0.0f, 1.0f)..... meaning the sign was lost somewhere in the dot product calculation I believe.

I'll try to paste the pertinent code below ......

/*
* OnStarting
*
* Called when the game engine's OnStarting method gets called before
* any frames are drawn.
*/
public void OnStarting(GraphicsDevice device)
{

Random rand = new Random();

// initialize attributes

this.Drawer = new SpriteBatch(device);
this.Texture = Texture2D.FromFile(device, texturePath);

this.Heading = new Vector2(0.0f, 1.0f);

// normalize the heading
this.Heading.Normalize();
Vector2 straight = new Vector2(1.0f, 0.0f); // default orientation -->


// get a vector for rotation --> dot product between perfectly right and the current heading
this.rotation = (Heading.X*straight.X) + (Heading.Y*straight.Y); // dot product formula
this.rotation = Math.Acos(this.rotation);

}

/*
* Update
*
* Called every frame to update
*/
public void Update(float dt)
{
this.Position += this.Heading;
}


/*
* Draw
*
* Called every frame to render
*/
public void Draw()
{
// I think this is relative to the texture (0, 0), but not sure
Rectangle src = new Rectangle(0, 0, this.Texture.Width, this.Texture.Height);

this.Drawer.Begin(SpriteBlendMode.AlphaBlend);

// this.Drawer.Draw(this.Texture, this.Position, Color.White);

this.Drawer.Draw( this.Texture,
this.Position,
src,
Color.White,
(float)this.rotation,
new Vector2(this.Texture.Width/2, this.Texture.Height/2),
1.0f,
SpriteEffects.None,
1.0f);

this.Drawer.End();
}

Any help would be greatly appreciated. I'll keep slugging through math books =)

[9031 byte] By [Haylwood] at [2007-12-25]
# 1

Hmm,

dot products tell you nothing about which direction the rotation should be, and so angle returned by rearranging a dot product will be in the range [0 , 180] degrees. Think about the fact that you can always get from vector a to vector b with a +ve and a -ve rotation (e.g. +90 degrees or -270 degrees). A DP will return the rotation with the smaller magnitude.

You could either resort to using basic trig, or alternatively (given that you know the direction of one of the vectors to start with) look at the y component of the direction vector, which should tell you whether the rotation is +ve or -ve. If you didn't know either of the vectors at coding time you could project the target vector onto the perpendicular of the start vector using another DP and the sign of this would tell you the direction.

Andy.

AndyL at 2007-10-8 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...
# 2
System.Math.Atan2 is useful for converting a vector heading format into a rotation angle.
ShawnHargreaves at 2007-10-8 > top of Msdn Tech,Game Technologies: DirectX, XNA, XACT, etc.,XNA Game Studio Express...