Двумерные евклидовы векторные вращения

У меня есть евклидово вектор 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!