Sign in to follow this  
Spa8nky

How do I correctly translate a polygon?

Recommended Posts

Spa8nky    230
I can translate a 2D rectangle correctly by using its centre: world_Transform = Matrix.CreateScale(extents.X * 2f, extents.Y * 2f, 0f) * Matrix.CreateTranslation(new Vector3(centre, 0f)); I can then draw the rectangle using its world transform and the position and centre will be correct. I now create a polygon consisting of 3 points:
            Vector2 D = new Vector2(0, 0);      // This isn't drawn at (0,0,0)
            Vector2 E = new Vector2(5, 0);
            Vector2 F = new Vector2(0, 10);
            debug_Polygon2D[1] = new CD_Polygon(true, D, E, F);

If I then use the centroid of this polygon [(D+E+F)/3] to calculate its world transform then that will not work: world_Transform = Matrix.CreateScale(scale) * Matrix.CreateRotationZ(0) * Matrix.CreateTranslation(centroid.X, centroid.Y, 0f); E.G. The polygon point D won't be drawn starting at (0,0,0). Also, if I need to obtain something in world space coordinates, then the above will not work. For example:
        public void GetSlab(Vector2 axis, ref float min, ref float max)
        {
            Vector2[] v_Transformed = vertices;

            for (int i = 0; i < vertices.Length; i++)
            {
                v_Transformed[i] = Vector2.Transform(vertices[i], World_Transform);
            }

            // Set min and max to first vertex axis dot product
            min = Vector2.Dot(v_Transformed[0], axis);
            max = min;

            // Loop through the remaining vertices to compare min/max values
            for (int i = 1; i < v_Transformed.Length; i++)
            {
                float d = Vector2.Dot(v_Transformed[i], axis);

                if (d < min)
                {
                    min = d;
                }
                else if (d > max)
                {
                    max = d;
                }
            }
        }

How can I translate a polygon correctly in this case and where have I gone wrong? Thank you.

Share this post


Link to post
Share on other sites
haegarr    7372
It is likely that your method works for the rectangle just because the center is at local (0,0), making the translation an identity transformation. But using the barycenter of the given triangle yields in a non-identity translation.

If you want a particular point P to be mapped onto a specific position O then you need to use the translation from the difference vector
O - P =: d
because then
P + d = P + ( O - P ) = O

Now, the P in your case is the D but after a scaling and a rotation is done:
P := D * S * R

And the requested position O is ( 0, 0 )
O := ( 0, 0 )

In total:
d = ( 0, 0 ) - D * S * R


Just in case that D = ( 0, 0 ) as is likely for your example with the rectangle, it happens that
d = ( 0, 0 ) - ( 0, 0 ) * S * R = ( 0, 0 )
and your center is mapped more accidentally than intentionally onto ( 0, 0 ).

So use the calculation method of d as shown above, and the transformation should work as wanted.

Share this post


Link to post
Share on other sites
Spa8nky    230
Thank you very much haegarr.

Just to confirm that I have understood you correctly, is this what you meant:


world_Transform = Matrix.CreateTranslation(-centroid.X, -centroid.Y, 0f) * // Translate centroid to origin first
Matrix.CreateScale(scale) *
Matrix.CreateRotationZ(0) *
Matrix.CreateTranslation(position.X, position.Y, 0f);


Where position is initialised to (0,0).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this