Если вы хотите повернуть объект вокруг его центра, сначала вы должны перевести его в начало координат, а затем повернуть и перевести его обратно. Поскольку матрицы преобразования влияют на ваши векторы справа налево, вы должны кодировать эти шаги в обратном порядке.
Вот некоторый псевдокод, поскольку я не знаю подпрограмм OpenGL наизусть:
PushMatrix();
LoadIdentity(); // Start with a fresh matrix
Translate(); // Move your object to its final destination
Rotate(); // Apply rotations
Draw(); // Draw your object using coordinates relative to the object center
PopMatrix();
Эти матрицы применяются:
v_t = (I * T * R) * v = (I * (T * (R * v)))
Итак, порядок: Вращение, Перевод.
РЕДАКТИРОВАТЬ: Объяснение для уравнения выше.
Вращение, масштаб и перемещение преобразований влияют на модель-вид-матрицу . Каждая трехмерная точка (вектор) вашей модели умножается на эту матрицу, чтобы получить ее конечную точку в трехмерном пространстве, а затем умножается на матрицу проекции , чтобы получить 2D точку (на вашем 2D-экране). 1020 *
Игнорируя материал проекции, ваша точка, преобразованная матрицей вида модели:
v_t = MV * v
Значение исходной точки v
, умноженное на матрицу вида модели MV
.
В приведенном выше коде мы построили MV
по единичной матрице I
, переводу T
и повороту R
:
MV = I * T * R
Собрав все воедино, вы увидите, что на вашу точку v
сначала влияет вращение R
, а затем перевод T
, так что ваша точка поворачивается до того, как она будет переведена, как мы и хотели :
v_t = MV * v = (I * T * R) * v = T * (R * v)
Вызов Rotate () перед Translate () приведет к:
v_t = (I * R * T) * v = R * (T * v)
, что было бы плохо: переведено в какую-то точку в 3D, затем повернуто вокруг начала координат, что привело к странным искажениям в вашей модели.