# Matrix transforms in XNA

So in my most recent 2D game I draw objects like so.

_spriteBatch.Draw(_sprite, Center(), null, Color.White, _rotation, new Vector2(_sprite.Width / 2, _sprite.Height / 2), _scale, SpriteEffects.None, 0);

My bounding boxes are generated using a two step algorithm where I make the transform matrix, then apply it to a Rectangle of the sprite's height and width.

    public Rectangle BoundingBoxTransformed
{
get
{
//Center and rotate our Rectangle

Matrix m = Matrix.CreateScale(_scale) *
Matrix.CreateTranslation(new Vector3(new Vector2((float)-BoundingBox.Width / 2, (float)-BoundingBox.Height / 2), 0.0f)) *
Matrix.CreateRotationZ(_rotation) *
//Move our rectangle toward the player, then recenter it by undoing the original translation (now that it's already rotated)

Matrix.CreateTranslation(new Vector3(_location, 0.0f)) * Matrix.CreateTranslation(new Vector3((float)BoundingBox.Width / 2, (float)BoundingBox.Height / 2, 0.0f));
return CalculateBoundingRectangle(new Rectangle(0, 0, _sprite.Width, _sprite.Height), m);
}
}


This is how I've been finding the new sizes for the scaled bounding boxes.

   public static Rectangle CalculateBoundingRectangle(Rectangle rectangle,
Matrix transform)
{
// Get all four corners in local space
Vector2 leftTop = new Vector2(rectangle.Left, rectangle.Top);
Vector2 rightTop = new Vector2(rectangle.Right, rectangle.Top);
Vector2 leftBottom = new Vector2(rectangle.Left, rectangle.Bottom);
Vector2 rightBottom = new Vector2(rectangle.Right, rectangle.Bottom);
// Transform all four corners into work space
Vector2.Transform(ref leftTop, ref transform, out leftTop);
Vector2.Transform(ref rightTop, ref transform, out rightTop);
Vector2.Transform(ref leftBottom, ref transform, out leftBottom);
Vector2.Transform(ref rightBottom, ref transform, out rightBottom);
// Find the minimum and maximum extents of the rectangle in world space
Vector2 min = Vector2.Min(Vector2.Min(leftTop, rightTop),
Vector2.Min(leftBottom, rightBottom));
Vector2 max = Vector2.Max(Vector2.Max(leftTop, rightTop),
Vector2.Max(leftBottom, rightBottom));
// Return that as a rectangle
return new Rectangle((int)min.X, (int)min.Y,
(int)(max.X - min.X), (int)(max.Y - min.Y));
}


I thought that I had the transformations all figured out, but when I run the game, I can see that my bounding boxes do not match up with my sprites.

So what is it that's going on here? Are my transformations out of order? Quick edit: The purple boxes are the original bounding boxes, which are used to determine the height and width of the red (transformed, i.e. scaled and rotated) bounding boxes.

• What is _rotation? You should confirm it with a break point while debugging. – Seth Battin Jun 18 '13 at 3:41
• @SethBattin I've added a picture to the question showing the rotations of various rotated/unrotated sprites. The bug exists at all angles, but rotation seems to be working as expected. – SomeGuy Jun 18 '13 at 4:38

I think this may be your problem:

Matrix.CreateTranslation(new Vector3(new Vector2((float)-BoundingBox.Width / 2, (float)-BoundingBox.Height / 2), 0.0f))


It appears you are trying to create a translation to the point of origin, which is what you should do when creating a rotation matrix, however, you are creating it based on your BoundingBox width and height. This should be your sprites original width and height.

Vector2 origin = new Vector2(_location.X + _sprite.Width / 2, _location.Y + _sprite.Height / 2);

Matrix m = Matrix.CreateTranslation(new Vector3(-origin), 0.0f)) *
Matrix.CreateScale(_scale) *
Matrix.CreateRotationZ(_rotation) *
Matrix.CreateTranslation(new Vector3(_location, 0.0f)) *
Matrix.CreateTranslation(new Vector3(origin, 0.0f));


And then in your draw code:

_spriteBatch.Draw(_sprite, _location, null, Color.White, _rotation, origin, _scale, SpriteEffects.None, 0);

• No luck with chaging the code there, though I've done it anyways since it's cleaner this way. I feel like if it were an issue with the scaling matrix, the rectangle would come out too large/small, rather than off-center, but I'm not really sure how matrices work. – SomeGuy Jun 18 '13 at 16:30
• @SomeGuy To me it looks like you have the right dimensions, it just seems like you have a Translation that is slightly off. Almost seems like the point of origin is off by a few pixels or something. – jgallant Jun 18 '13 at 16:46
• whoops, I mixed you up with a discussion I was having on steam about scaling matrices, sorry about that. Your code was giving me some issues at first due to the way I was drawing sprites originally (I was drawing from the center, which was throwing the origin off a little). Having updated the code, it works beautifully, save that the boxes are sometimes a pixel or two too small due to rounding errors. Nice catch! – SomeGuy Jun 18 '13 at 16:51