旋转多部分对象 [英] Rotating a multipart object

查看:21
本文介绍了旋转多部分对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个对象,它有大约 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 by x y z . The current matrix (see glMatrixMode) 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 vector x y z . The current matrix (see glMatrixMode) 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆