旋转多部分对象 [英] Rotating a multipart object
问题描述
我创建了一个对象,它有大约 7 个以上的部分,包括它的身体和在不同位置附加"到它的较小部分.我的目标是旋转整个对象.我试图在构造整个对象之前简单地调用 glRotatef(angle, 0, 1, 0)
,但我意识到这似乎围绕原点旋转一切",无论平移如何.下面的代码试图旋转身体本身并旋转它的附加部分.
//glRotatef(angle, 0, 1, 0);//旋转对象的旧方法//身体glPushMatrix();//移动glTranslatef(subx, suby + y, subz);//旋转身体本身glRotatef(角度, 0, 1, 0);//身体的起始位置glScalef(9.0, 1.75, 1.75);glTranslatef(-subx, -suby, -subz);glTranslatef(subx, suby, subz);glutSolidSphere(1.0, 50, 50);glPopMatrix();//附加部分glPushMatrix();//移动glTranslatef(rot1x, rot1y + y, rot1z);//尝试在附加到"身体时旋转零件glRotatef(角度, 0, 1, 0);//将零件放在对象上的起始位置glRotatef(rot1angle, rot1xrot, rot1yrot, rot1zrot);glTranslatef(-rot1x, -rot1y, -rot1z);glTranslatef(rot1x, rot1y, rot1z);gluPartialDisk(gluNewQuadric(), 0, 1, 50, 1, 0, 100.0);glPopMatrix();
我似乎无法理解需要发生什么才能使对象的较小部分与对象的身体一起正确旋转(固定点?).感谢您的帮助.
矩阵栈上的操作是基于彼此的.每个操作的参考系统是当前的变换.如果要转换由一堆对象组成的对象,则必须知道每个子对象与对象联合的参考位置的相对位置.那么你必须执行以下步骤:
- 将每个对象移动到世界上的一个共同位置(
glTranslate
). - 定位对象(
glRotate
) - 将每个对象移动到它在对象联合中的相对位置
//在世界中的动态位置浮动 refPosX、refPosY、refPosZ;//动态方向浮动角度;//子对象相对于对象联合的恒定位置浮动 subPosX[], subPosY[], subPosZ[];for ( int i = 0 i < noOfObj, ++i )//对于每个对象{glPushMatrix();glTranslatef(refPosX, refPosY, refPosZ);glRotatef(角度, 0, 1, 0);glTranslatef(subPosX[i], subPosY[i], subPosZ[i]);glScalef(9.0, 1.75, 1.75);.....//在这里绘制对象glPopMatrix();}
请参阅
注意,rotate * translate
的结果是:
model[0] : ( cos(angle), 0, sin(angle), 0 )模型[1] : ( 0, 1, 0, 0 )模型[2] : ( -sin(angle), 0, cos(angle), 0 )模型[3] : ( cos(angle)*tx - sin(angle)*tx, ty, sin(angle)*tz + cos(angle)*tz, 1 )
I've created an object that has about 7+ parts to it including its body and smaller parts that 'attach' to it in different places. My goal is to rotate the entire object. I tried to simply call glRotatef(angle, 0, 1, 0)
before constructing the entire object, but I realize that this seems to rotate 'everything' around the origin, no matter the translation. The following code was an attempt to rotate the body itself and rotate the attached parts to it.
// glRotatef(angle, 0, 1, 0); //old way of rotating the object
// body
glPushMatrix();
// movement
glTranslatef(subx, suby + y, subz);
//rotating the body itself
glRotatef(angle, 0, 1, 0);
// starting position of the body
glScalef(9.0, 1.75, 1.75);
glTranslatef(-subx, -suby, -subz);
glTranslatef(subx, suby, subz);
glutSolidSphere(1.0, 50, 50);
glPopMatrix();
// attached part
glPushMatrix();
// movement
glTranslatef(rot1x, rot1y + y, rot1z);
// attempting to rotate the part while 'attached to' the body
glRotatef(angle, 0, 1, 0);
//placing the part on the object in starting position
glRotatef(rot1angle, rot1xrot, rot1yrot, rot1zrot);
glTranslatef(-rot1x, -rot1y, -rot1z);
glTranslatef(rot1x, rot1y, rot1z);
gluPartialDisk(gluNewQuadric(), 0, 1, 50, 1, 0, 100.0);
glPopMatrix();
I can't seem to wrap my head around what needs to happen in order for the smaller parts of the object to rotate properly with the object's body (a fixed point?). Thanks for your help.
The operations on the matrix stack are based on one another. The reference system of each operation is the current transformation. If you want to transform a object which consists of a bunch of objects, then you have to know the relative position of each sub object to a reference position of the object union. Then you have to do the following steps:
- Move each object to a common position in the world (
glTranslate
). - Orientate the objects (
glRotate
) - Move each object to its relative position in the object union
// dynamic position in the world
float refPosX, refPosY, refPosZ;
// dynamic orientation
float angle;
// constant positions of the sub object relative to the object union
float subPosX[], subPosY[], subPosZ[];
for ( int i = 0 i < noOfObj, ++i ) // for each object
{
glPushMatrix();
glTranslatef(refPosX, refPosY, refPosZ);
glRotatef(angle, 0, 1, 0);
glTranslatef(subPosX[i], subPosY[i], subPosZ[i]);
glScalef(9.0, 1.75, 1.75);
..... // draw the object here
glPopMatrix();
}
See the documentation of glTranslate
:
glTranslate
produces a translation byx y z
. The current matrix (seeglMatrixMode
) is multiplied by this translation matrix, with the product replacing the current matrix,
and see the documentation of glRotate
:
glRotate
produces a rotation of angle degrees around the vectorx y z
. The current matrix (seeglMatrixMode
) is multiplied by a rotation matrix with the product replacing the current matrix,
Note, the translation matrix looks like this:
Matrix4x4 translate;
translate[0] : ( 1, 0, 0, 0 )
translate[1] : ( 0, 1, 0, 0 )
translate[2] : ( 0, 0, 1, 0 )
translate[3] : ( tx, ty, tz, 1 )
And the rotation matrix around Y-Axis looks like this:
Matrix4x4 rotate;
float angle;
rotate[0] : ( cos(angle), 0, sin(angle), 0 )
rotate[1] : ( 0, 1, 0, 0 )
rotate[2] : ( -sin(angle), 0, cos(angle), 0 )
rotate[3] : ( 0, 0, 0, 1 )
A matrix multiplication works like this:
Matrix4x4 A, B, C;
// C = A * B
for ( int k = 0; k < 4; ++ k )
for ( int l = 0; l < 4; ++ l )
C[k][l] = A[0][l] * B[k][0] + A[1][l] * B[k][1] + A[2][l] * B[k][2] + A[3][l] * B[k][3];
The result of translate * rotate
is this:
model[0] : ( cos(angle), 0, sin(angle), 0 )
model[1] : ( 0, 1, 0, 0 )
model[2] : ( -sin(angle), 0, cos(angle), 0 )
model[3] : ( tx, ty, tz, 1 )
Note, the result of rotate * translate
would be:
model[0] : ( cos(angle), 0, sin(angle), 0 )
model[1] : ( 0, 1, 0, 0 )
model[2] : ( -sin(angle), 0, cos(angle), 0 )
model[3] : ( cos(angle)*tx - sin(angle)*tx, ty, sin(angle)*tz + cos(angle)*tz, 1 )
这篇关于旋转多部分对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!