Ну, вы можете использовать скалярное произведение, чтобы получить угол между двумя векторами. Формула следующая:
cos(phi) = (a * b) / (|a|*|b|)
Что преобразуется в это:
phi = acos((ax*bx + ay*by + az * bz) / (sqrt(ax^2 + ay^2 + az^2)+sqrt(bx^2 + by^2 + bz^2)))
Теперь скалярное произведение симметрично, что означает: (1,1,1) (2,2,2) дает тот же результат, что и (2,2,2) (1,1,1) . Следовательно, вам нужно добавить еще один шаг. Добавляя третий вектор, угол которого к первому заданному вектору вам известен, вы можете проверить истинный угол между двумя векторами. Отказ от привязки к этому опорному вектору можно выполнить, повернув первый вектор вокруг оси; теперь, чтобы убедиться, что это действительная опорная точка, он должен находиться в той же плоскости, что и векторы a и b. Это означает, что ваша ось для поворота вашего первого вектора должна быть ортогональна векторам 1 и 2, векторное произведение двух векторов дает вектор, ортогональный обоим, поэтому мы будем использовать полученный таким образом вектор в качестве оси.
axis = a x b
Это равно:
axis = (aybz-azby, azbx-axbz, axby-aybx)
Чтобы повернуть вектор на заданную величину вокруг оси, необходимо сделать следующее:
double R[3][3] = {};
Vector axis = Axis.getUnitVector();
double deg = degrees / 180 * M_PI;
R[0][0] = axis.X * axis.X * (1 - cos(deg)) + cos(deg); R[0][1] = axis.X * axis.Y * (1 - cos(deg)) - axis.Z * sin(deg); R[0][2] = axis.X * axis.Z * (1 - cos(deg)) + axis.Y * sin(deg);
R[1][0] = axis.Y * axis.X * (1 - cos(deg)) + axis.Z * sin(deg); R[1][1] = axis.Y * axis.Y * (1 - cos(deg)) + cos(deg); R[1][2] = axis.Y * axis.Z * (1 - cos(deg)) - axis.X * sin(deg);
R[2][0] = axis.Z * axis.X * (1 - cos(deg)) - axis.Y * sin(deg); R[2][1] = axis.Z * axis.Y * (1 - cos(deg)) + axis.X * sin(deg); R[2][2] = axis.Z * axis.Z * (1 - cos(deg)) + cos(deg);
double x = this->X * R[0][0] + this->Y * R[0][1] + this->Z * R[0][2];
double y = this->X * R[1][0] + this->Y * R[1][1] + this->Z * R[1][2];
double z = this->X * R[2][0] + this->Y * R[2][1] + this->Z * R[2][2];
Единичный вектор определяется следующим образом:
e_a = (ax / sqrt(ax^2+ay^2+az^2),ay / sqrt(ax^2+ay^2+az^2),az / sqrt(ax^2+ay^2+az^2))
Используя эту новую ось, мы можем повернуть наш первый вектор на 90 °. Вычислив угол между нашей ссылкой и вторым вектором, мы можем теперь оценить реальный угол между первым и вторым векторами. Если угол к точке отсчета больше 90 °, 2-й вектор находится в 3-м или 4-м секторе или в декартовой системе координат, что означает, что для получения реального угла нам придется вычесть полученный угол между первым и 2-м векторами из 360 °. Если угол относительно опорной точки меньше 90 °, вычисленный угол является действительным.
Теперь возникает другой вопрос: что / где север? Если бы мы знали север, мы могли бы просто вычислить угол между севером и двумя векторами, и тот, у которого угол меньше, был бы более северным. Это означает, что нет причин оценивать опорный вектор или строить и применять матрицу вращения.
В случае фиксированного севера вы также можете спроецировать свои векторы на плоскость, содержащую север, и упростить необходимые вычисления. Предоставьте дополнительную информацию, и я отредактирую это.
edit: / поскольку вы указываете север и вектор игрока, просто вычислите угол между ними.
person
Y.S
schedule
28.03.2018
*=
следует заменить на*
. - person Jarod42   schedule 28.03.2018