Jump to content
  • Advertisement
Sign in to follow this  
ltschofield

rotating 2D rectangle *something wrong*

This topic is 3675 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone I'm new around here and to programming really but i recently decided to have a crack at doing some graphical programming and i am determined to do as much of the computation of the graphics via my own understanding as possible. I am using XNA to get myself starded as quick as possible and in terms of is graphical capabilities am using it only to draw primative 2D objects the rest i am trying to do on my own. I started with drawing a rectangle and once i had that up and running i worked on translation and scaling. Now i am up to the rotation of the object and i applied the concepts i learnt on complex numbers in my final year of high school to find the new x and y coordinates after rotating. this is what i came up with

public void rotate(float radians, Vector3 pivot)
{

            float offsetX; //initial x-coord in relation to pivot
            float offsetY; //initial y-coord in relation to pivot
            float newX;
            float newY;
            float r; //radius magnitude from pivot
            float angle; //angle before rotation
            float finalAngle = 0; //angle after rotation

            for (int i = 0; i < RectangleVertex.Length; i++)
            {
                //work out offset X
                offsetX = RectangleVertex.Position.X - pivot.X;

                //work out offset Y
                offsetY = RectangleVertex.Position.Y - pivot.Y;

                //work out r
                r = (float)Math.Sqrt((offsetX * offsetX) + (offsetY * offsetY));

                //work out current angle
                angle = (float)Math.Atan2((float)offsetY, (double)offsetX);

                //work out new angle
                finalAngle = angle + radians;

                //work out new x
                newX = r * (float)(Math.Cos((double)finalAngle));

                //work out new y
                newY = r * (float)(Math.Sin((double)finalAngle));

                //change position
                RectangleVertex.Position.X = newX;
                RectangleVertex.Position.Y = newY;
            }
}


I set the pivot to the rectangles center coordinates. My screen is set up like a cartesian plane ( point (0, 0, 0) in the center ) and the rectangle i create starts off with its center point at (0, 0, 0). At this location the rotation works perfectly and there is no problem. The problem occurs when i translate the rectangle, changing its center point and therefore its pivot. Once i do this the rectangle still rotates in a circular path but it's as if the pivot is now outside the rectangle and it is no longer pivoting at its center, the more i move the rectangle around the larger its rotating path becomes. I have looked at the code many times but i cant find the problem myself. I also know there are other ways to do this and i have tried some of them to the same effect such as
newX = offsetX * (float)Math.Cos(radians) - offsetY * (float)Math.Sin(radians);

but i have the same problem. any help is greatly appriciated.

Share this post


Link to post
Share on other sites
Advertisement
Converting to polar co-ordinates for rotation is unusual in graphics, but nonetheless totally legal. Usually one would use matrices.

However, the "problem" you describe comes from the fact that during rotation in 2D only 1 point is guaranteed to be mapped onto itself, and that is (0,0); therefore this point is often called the origin of rotation. If you want to have another origin, you have to make those point temporarily (0,0) by translation. I.e., if (x0,y0) is the said desired origin, do
translate( -x0, -y0 )
rotate( ... )
translate( x0, y0 )

Obviously, (x0,y0) becomes (x0-x0,y0-y0) == (0,0) by step one, is hence mapped onto itself (0,0) during step 2, and then translated back to (0+x0,0+y0)==(x0,y0) by step 3, so that it comes to rest where it was at the beginning.

Share this post


Link to post
Share on other sites
Thanks those changes worked great. However, moving it to the center and back again seems ineffecient (very minutely) but still, is there another way to do rotation so that you don't have to move it to (0,0).
Thanks once again.

Share this post


Link to post
Share on other sites
It seems inefficient because you perform the transformation one-by-one. Here comes the already mentioned matrix math into play. With matrices, you are able to compute a composite matrix once and apply it to all vertices in a single step. With the given example, you have a translation, a rotation, and a 2 part translational correction for the origin. As matrices, it may look like this composition (using column vectors)
M := T * O * R * O-1
with M denoting the resulting composite matrix, T the translation, R the rotation, and O the translation to the origin.

Now, when you apply this step-by-step to a vertex v, you would do
v' := T * ( O * ( R * ( O-1 * v ) ) )
but fortunately, due to matrix math rules, the parantheses play no role. So the result is identical to
v' = ( ( ( T * O ) * R ) * O-1 ) * v
or, in other terms, simply
v' = M * v

Hence you can compute the transformation once into a composite matrix (here M) and perform the overall transformation in one step per vertex. This is the way graphics APIs like OpenGL and D3D do the job internally. Of course, you can use this way only for transformatons that can be expressed by matrices at all, but those are sufficient for most cases.


EDIT: I doubt that you can perform a rotation around an arbitrary point w/o doing the correction in the one or other way. Functions/operators are thought to manipulate values, and indentity mappings will IMHO ever be restricted to a small amount (presumbly one) value.

Share this post


Link to post
Share on other sites
ok well i'll keep fighting along, i am eventually going to use matrices, but right now i haven't learnt them/can't remember how they work, so for now i will continue the way i am, until i learn matricies again properly, or am forced to if i cant accomplish something using the polar coordinates rotation method.
thanks again the problem took up a couple of hours for me.

Share this post


Link to post
Share on other sites
(Homogeneous) matrices are fine in this sense because they allow to express (among others) rotation, translation, scaling, shearing, and orthogonal as well as perspective projection, just allowing to compose them into a single transformation. Using distinct transformation methods usually forbid to do so. However, please notice that composing consecutive transformations of the same type is (probably) ever possible.

E.g. in the example above,
T * O * R * O-1
there are 2 consecutive translations, namely T * O. So it is possible for you, even if you use "polar rotation", to compose the origin reconstruction and desired translation into a single translation, reducing the effort from 4 transformations down to 3 (okay, that's not the big hit, but shows the principle).

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!