I'm trying to get a rotated Texture2D
to properly fit within/fill the bounds of a rotated Polygon
(my own class), but it refuses to work properly. The SpriteBatch
method I am using is:
spriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), null, color, Rotation, Vector2.Zero, SpriteEffects.None, 1.0f);
However, the only important bits in this are the Rectangle
and the origin, which is currently set to Vector2.Zero
. When the above is run, it produces this image, where the Texture2D
(a filled red square) is offset from the Polygon
(the lime wireframe) by a value of (texture.Width / 2, texture.Height / 2)
. However, the rotation is correct, since both shapes have parallel sides.
I have tried:
spriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), null, color, Rotation, new Vector2(Width / 2, Height / 2), SpriteEffects.None, 1.0f);
The only difference in this call is that I changed the origin (the point around which the Texture2D
should be rotated) to new Vector2(Width / 2, Height / 2)
, which results in this image, where the Texture2D
is offset from the Polygon
by a value of (-Width, -Height)
, but it still rotates with the Polygon
.
Another error that occurs is that when using a different Texture2D
with a different width and height from the first-- although it should produce the same result since the destinationRectangle
field does not change-- it is different in the program, as shown in this image. Again, this uses the exact same call as the previous, just with a different image (with different dimensions).
Any help on either of these issues would be greatly appreciated. Thanks!
The answer to both of my problems lies in one mistake:
SpriteBatch applies the rotation around the origin before applying scale translation.
To explain this, here's an example:
You have a Texture2D
of size (16, 16)
, and want it to fill a (48, 48)
size destinationRectangle
while rotating around origin point (destinationRectangle.Width / 2, destinationRectangle.Height / 2)
(which is equal to (24, 24)
). So, you want to end up with a square rotated around its center point.
First, SpriteBatch
will rotate the Texture2D
around point (24, 24)
, which, because the Texture2D
has not yet been scaled and therefore is of size (16, 16)
, will result in an improper and unexpected result. After this, it will be scaled, making it just a larger version of the poorly rotated square.
To remedy this problem, use (texture.Width / 2, texture.Height / 2)
instead of (destinationRectangle.Width / 2, destinationRectangle.Height / 2)
as the origin point.
Example:spriteBatch.Draw(texture, new Rectangle((int)Position.X, (int)Position.Y, Width, Height), null, color, Rotation, new Vector2(texture.Width / 2, texture.Height / 2), SpriteEffects.None, 0f);