4
\$\begingroup\$

I use a 1x1 pixel 2d texture as source for SpriteBatch.Draw. The texture is scaled and rotated around an origin. The left image is only scaling. The right one scaling + rotation around the origin at the bottom center. I need the right image as result. i.e. scaled to 5x10 and rotated around 2.5x10

enter image description here

The problem is with the 1x1 texture the draw starts to act strange if the origin parameter is outside the source texture. And as long as the origin is limited to a max of 1x1 its not possible to rotate around the bottom center of the scaled texture.

Why does the origin behave strangely if it is outside the source texture? With strange I mean the texture moves much more then the origin value set. i.e. if its origin x=10 the texture moves much more then 10 pixels.

\$\endgroup\$
1
  • \$\begingroup\$ Are you scaling first, then rotating? It might be just a case of changing the order in the transform. Change the order, and see if it fixes itself \$\endgroup\$ Feb 15, 2013 at 9:20

3 Answers 3

5
\$\begingroup\$

I think you are misinterpretting the result of setting the origin to (0.5f, 1). I did the same thing, and I got the expected results. Here's a modified version of the code I ran at this answer:

Color[] colors = new Color[] { Color.White };
texture = new Texture2D(GraphicsDevice, 1, 1);
texture.SetData<Color>(colors);

spriteBatch.Draw(texture, new Rectangle(100, 50, 100, 100), null, Color.Green);
spriteBatch.Draw(texture, new Rectangle(100, 225, 100, 100), null, Color.Yellow, 0, new Vector2(0, 0), SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Rectangle(100, 400, 100, 100), null, Color.Pink, 0, new Vector2(0.5f, 1f), SpriteEffects.None, 0);

spriteBatch.Draw(texture, new Rectangle(400, 50, 100, 100), null, Color.Red, MathHelper.PiOver4, Vector2.Zero, SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Rectangle(400, 225, 100, 100), null, Color.Orange, MathHelper.PiOver4, new Vector2(0, 0), SpriteEffects.None, 0);
spriteBatch.Draw(texture, new Rectangle(400, 400, 100, 100), null, Color.Blue, MathHelper.PiOver4, new Vector2(0.5f, 1f), SpriteEffects.None, 0);

And as you can see, the blue square rotates around the bottom-center, exactly as intended. The other squares rotate around (0,0).

enter image description here

\$\endgroup\$
1
\$\begingroup\$

Set origin in relation to source rectangle. If your rectangle is 0:0:1:1, set 0.5:1 origin (for bottom center).

\$\endgroup\$
2
  • \$\begingroup\$ Yes that's how I would expect it to work. But when doing that it rotates the 5x10 texture around the 0.5:1 origin (top left). The order seems to be wrong. Xna scales first and rotates afterwards with the unscaled origin. \$\endgroup\$
    – user26297
    Feb 14, 2013 at 13:53
  • \$\begingroup\$ @user26297 This method is correct. I demonstrated it in my screenshot. \$\endgroup\$ May 16, 2013 at 2:30
1
\$\begingroup\$

I think you should divide origin by the scale...

because spritebatch apply origin translation before the scale operation, so you have to invert the scale operation to avoid origin being scaled

\$\endgroup\$
2
  • 2
    \$\begingroup\$ This should probably be a comment. \$\endgroup\$ Apr 15, 2013 at 18:52
  • \$\begingroup\$ you are right... but was the solution... I've added more explanations \$\endgroup\$
    – Blau
    Apr 15, 2013 at 22:44

You must log in to answer this question.

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