views:

113

answers:

5

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;
    }
+3  A: 

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 :)

Jon Skeet
+1 for suggesting readability improvements. We need more people coding for the next programmer who will maintain the code.
Dysaster
A: 

Just a wild guess - are you sure the aspect ratio of your desktop resolution is the same as of the physical screen? That is, are the pixels square? If not, then rotating your rectangles in an arbitrary angle can make them look skewed.

ysap
I haven't had a screen with anisotropic pixels since EGA times (640x400) - I thought those beasts went the way of the dinosaur!
nikie
@nikie - not necessarily the physical pixel. You can choose a resolution different than the native screen res. This way you can get rectangular "logical" pixels when your desktop is stretched to fill the physical screen area.
ysap
+4  A: 

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. :)

Dysaster
+2  A: 

I think your rotation matrix is incorrect. There should be a + instead of - in the second equation:

+cos  -sin
+sin  +cos
ysap
+1  A: 

Assuming that origin is 0,0. From your formula I would get: X' = (X + ((X - 0) * Cos(angle)) - ((Y - 0) * Sin(angle))); X' = X + (X * Cos(angle)) - (Y * Sin(angle));

Which differs from the initial formula x' = x * cos angle - y * cos angle

So I think Jon Skeet's answer is correct and clearer.

Txugo
correction, except for the y' value. the - should be +.
Txugo