Как сделать правильное вращение многоугольника?(в C #, хотя это относится ко всему) - PullRequest
8 голосов
/ 10 августа 2010

Привет! Я использую этот код C # для поворота многоугольников в моем приложении - они вращаются, но также меняются по пути, а это не то, чего я хочу.Все многоугольники являются прямоугольниками с четырьмя углами, определенными как 2D Векторы,

    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;
    }

Ответы [ 5 ]

7 голосов
/ 10 августа 2010

Похоже, ваше преобразование вращения неверно.Вы должны использовать:

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

Для получения дополнительной информации, проверьте различные источники в Интернете.:)

6 голосов
/ 10 августа 2010

У меня пока нет ответа на вопрос, почему происходит перекос, но у меня нет есть предложение сделать код более понятным:

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;
}

(при условии, что в Vector определены соответствующие операторы +/-.)

Возможно, вам все еще понадобится пара приведений к float, но у вас все равно останется меньше скобок, запутывающих вещи. О, и вам определенно не нужно привести angle к float, учитывая, что он уже объявлен как float.

РЕДАКТИРОВАТЬ: примечание о задействованных матрицах вращения - это зависит от того, берете ли вы угол по часовой стрелке или против часовой стрелки. Я совсем не удивлюсь, если узнаю, что матрица действительно идет не так (я пытался это проверить, но, по-видимому, испортил) ... но «другое» не означает обязательно"неправильно". Надеюсь, матрица это что не так, по общему признанию:)

3 голосов
/ 10 августа 2010

Я думаю, что ваша матрица вращения неверна.Во втором уравнении должно быть + вместо -:

+cos  -sin
+sin  +cos
1 голос
/ 10 августа 2010

Предполагая, что происхождение составляет 0,0.Из вашей формулы я получу: X '= (X + ((X - 0) * Cos (угол)) - ((Y - 0) * Грех (угол)));X '= X + (X * Cos (угол)) - (Y * Sin (угол));

Что отличается от исходной формулы x '= x * cos angle - y * cos angle

Так что я думаю, что ответ Джона Скита правильный и более четкий.

0 голосов
/ 10 августа 2010

Просто дикая догадка - вы уверены, что соотношение сторон вашего рабочего стола такое же, как у физического экрана? То есть пиксели квадрат ? Если нет, то при повороте прямоугольников на произвольный угол они могут выглядеть перекошенными.

...