Двумерные евклидовы векторные вращения
У меня есть евклидово вектор a
, сидящий в координатах (0, 1)
.
Я хочу повернуть a
на 90 градусов (по часовой стрелке) вокруг начала координат: (0, 0)
.
Если у меня есть правильное понимание того, как это должно работать, результирующие (x, y) координаты после вращения должны быть (1, 0)
.
Если бы мне пришлось вращать его на 45 градусов (по-прежнему по часовой стрелке), я бы ожидал, что результирующие координаты будут (0.707, 0.707)
.
theta = deg2rad(angle);
cs = cos(theta);
sn = sin(theta);
x = x * cs - y * sn;
y = x * sn + y * cs;
Используя приведенный выше код с значением angle
90,0 градусов, результирующие координаты: (-1, 1)
.
И я так смущен.
Примеры, показанные в следующих ссылках, представляют собой ту же формулу, которая была показана выше?
Чем я ошибся?
Или я неправильно понял, как вектор должен быть повернут?
Ответы
Ответ 1
вы должны удалить vars из функции:
x = x * cs - y * sn; // now x is something different than original vector x
y = x * sn + y * cs;
создавать новые координаты, чтобы избежать вычисления x до того, как он достигнет второй строки:
px = x * cs - y * sn;
py = x * sn + y * cs;
Ответ 2
Вращение вектора 90 градусов особенно просто.
(x, y)
повернутый на 90 градусов вокруг (0, 0)
равен (-y, x)
.
Если вы хотите повернуть по часовой стрелке, вы просто делаете это наоборот, получая (y, -x)
.
Ответ 3
Повернуть на 90 градусов на 0,0:
x' = -y
y' = x
Повернуть на 90 делений вокруг px, py:
x' = -(y - py) + px
y' = (x - px) + py
Ответ 4
Звучит проще со стандартными классами:
std::complex<double> vecA(0,1);
std::complex<double> i(0,1); // 90 degrees
std::complex<double> r45(sqrt(2.0),sqrt(2.0));
vecA *= i;
vecA *= r45;
Вращение вектора является подмножеством сложного умножения. Чтобы повернуть на angular alpha
, вы умножаете на std::complex<double> { cos(alpha), sin(alpha) }
Ответ 5
Вы вычисляете y-часть вашей новой координаты на основе "новой" x-части новой координаты. В основном это означает, что вы вычисляете новый результат с точки зрения нового выхода...
Попробуйте переписать в терминах ввода и вывода:
vector2<double> multiply( vector2<double> input, double cs, double sn ) {
vector2<double> result;
result.x = input.x * cs - input.y * sn;
result.y = input.x * sn + input.y * cs;
return result;
}
Затем вы можете сделать это:
vector2<double> input(0,1);
vector2<double> transformed = multiply( input, cs, sn );
Обратите внимание, что выбор правильных имен для ваших переменных может избежать этой проблемы alltogether!