Я не уверен, какую библиотеку вы используете, поэтому постараюсь дать несколько общих советов по этому вопросу.
Глобальное и локальное вращение - это вопрос порядка умножения матриц.Пусть R
будет конечной матрицей вращения.Когда вы умножаете матрицы X, Y и Z, используя следующий порядок R=X*Y*Z
, это даст вам Глобальные вращения , тогда как R=Z*Y*X
даст вам Локальные вращения .
Проблема с вышесказанным заключается в том, что оно ограничивает вашу свободу локальных вращений конкретным порядком ZYX.Например, если вы хотите повернуть, сначала по по оси X, затем по по оси Y, а затем по по оси Z,выше будет работать нормально.Все остальное не даст вам желаемых результатов.Вам придется изменить порядок умножения матриц.
Если вы хотите вращаться вокруг оси, скажем, ось y , которая является локальной для вашего объекта, тогда вы 'Мне нужно знать, где находится эта ось.Вам необходимо сохранять привязку к текущим осям после каждого преобразования, а затем использовать матрицу вращения от оси и угла , чтобы вращаться вокруг текущей локальной оси y .
/* from the wiki link above */
Mat3 Axis_Matrix(float angle_, const Vec3 &axis_)
{
return Mat3{ cos(angle_)+pow(axis_.x,2)*(1.0-cos(angle_)) , (axis_.x*axis_.y*(1.0-cos(angle_)))-(axis_.z*sin(angle_)) , (axis_.x*axis_.z*(1.0-cos(angle_)))+(axis_.y*sin(angle_)),
(axis_.y*axis_.x*(1.0-cos(angle_)))+(axis_.z*sin(angle_)) , cos(angle_)+pow(axis_.y,2)*(1.0 - cos(angle_)) , (axis_.y*axis_.z*(1.0-cos(angle_)))-(axis_.x*sin(angle_)),
(axis_.z*axis_.x*(1.0-cos(angle_)))-(axis_.y*sin(angle_)) , (axis_.z*axis_.y*(1.0-cos(angle_)))+(axis_.x*sin(angle_)) , cos(angle_)+pow(axis_.z,2)*(1.0 - cos(angle_)) };
}
Вы можете создать свою собственную структуру, которая делает все это:
struct CoordinateSystem
{
Vec3 current_x_axis;
Vec3 current_y_axis;
Vec3 current_z_axis;
Mat3 local;
void setRotationX(float angle_)
{
local *= Axis_Matrix(angle_, current_x_axis);
update();
}
void setRotationY(float angle_)
{
local *= Axis_Matrix(angle_, current_y_axis);
update();
}
void setRotationZ(float angle_)
{
local *= Axis_Matrix(angle_, current_z_axis);
update();
}
void update()
{
current_x_axis = {-1.f, 0.f, 0.f} * local;
current_y_axis = { 0.f, 1.f, 0.f} * local;
current_z_axis = { 0.f, 0.f,-1.f} * local;
}
};
Тогда вы можете просто сказать:
setRotationX(45);
setRotationZ(10);
setRotationY(62);
setRotationX(34);
setRotationY(81);
И все повороты будут локальными для вашегообъект.