2D евклидовы векторные вращения - PullRequest
46 голосов
/ 24 января 2011

У меня есть евклидов вектор 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). И я так чертовски смущен. Примеры, приведенные в следующих ссылках, точно соответствуют той же формуле, что и выше?

Что я сделал не так? Или я неправильно понял, как вращать вектор?

Ответы [ 5 ]

75 голосов
/ 24 января 2011

Поворот вектора на 90 градусов особенно прост.

(x, y) поворот на 90 градусов вокруг (0, 0) равен (-y, x).

Если вы хотите повернуть по часовой стрелке, вы просто делаете этонаоборот, получая (y, -x).

69 голосов
/ 24 января 2011

вы должны удалить переменные из функции:

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;
18 голосов
/ 19 октября 2012

Поворот на 90 градусов вокруг 0,0:

x' = -y
y' = x

Поворот на 90 градусов вокруг px, py:

x' = -(y - py) + px
y' = (x - px) + py
5 голосов
/ 24 января 2011

Звучит проще со стандартными классами:

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;

Вращение вектора является подмножеством сложного умножения.

5 голосов
/ 24 января 2011

Вы вычисляете 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 );

Обратите внимание, как выбор правильных имен для ваших переменных может полностью избежать этой проблемы!

...