Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do correct polygon rotation? ( in C# though it applies to anything )

Hi I'm using this C# code to rotate polygons in my app - they do rotate but also get skewed along the way which is not what i want to happen. All the polygons are rectangles with four corners defined as 2D Vectors,

    public Polygon GetRotated(float radians)
    {

        Vector origin = this.Center;
        Polygon ret = new Polygon();
        for (int i = 0; i < points.Count; i++)
        {
            ret.Points.Add(RotatePoint(points[i], origin, radians));
        }
        return ret;
    }

    public Vector RotatePoint(Vector point, Vector origin, float angle)
    {
        Vector ret = new Vector();
        ret.X = (float)(origin.X + ((point.X - origin.X) * Math.Cos((float)angle)) - ((point.Y - origin.Y) * Math.Sin((float)angle)));
        ret.Y = (float)(origin.Y + ((point.X - origin.X) * Math.Sin((float)angle)) - ((point.Y - origin.Y) * Math.Cos((float)angle)));
        return ret;
    }
like image 452
bharling Avatar asked Aug 10 '10 16:08

bharling


2 Answers

Looks like your rotation transformation is incorrect. You should use:

x' = x*Cos(angle) - y*Sin(angle)
y' = x*Sin(angle) + y*Cos(angle)

For more information, check various sources on the internet. :)

like image 144
vhallac Avatar answered Sep 20 '22 21:09

vhallac


I don't have any answer to why it's skewing yet, but I do have a suggestion to make the code clearer:

public Vector RotatePoint(Vector point, Vector origin, float angle)
{
    Vector translated = point - origin;
    Vector rotated = new Vector
    {
        X = translated.X * Math.Cos(angle) - translated.Y * Math.Sin(angle),
        Y = translated.X * Math.Sin(angle) + translated.Y * Math.Cos(angle)
    };
    return rotated + origin;
}

(That's assuming Vector has appropriate +/- operators defined.)

You may still need a couple of casts to float, but you'll still end up with fewer brackets obfuscating things. Oh, and you definitely don't need to cast angle to float, given that it's already declared as float.

EDIT: A note about the rotation matrices involved - it depends on whether you take the angle to be clockwise or anticlockwise. I wouldn't be at all surprised to find out that the matrix is indeed what's going wrong (I did try to check it, but apparently messed up)... but "different" doesn't necessarily mean "wrong". Hopefully the matrix is what's wrong, admittedly :)

like image 32
Jon Skeet Avatar answered Sep 17 '22 21:09

Jon Skeet