首先,这段代码:
glTranslated(m_rotationCenter.x, 0, 0);
glTranslated(0, m_rotationCenter.y, 0);
glTranslated(0, 0, m_rotationCenter.z);
glScalef( scale, scale, scale );
glTranslated(-m_rotationCenter.x, 0, 0);
glTranslated(0, -m_rotationCenter.y, 0);
glTranslated(0, 0, -m_rotationCenter.z);
glTranslated(m_rotationCenter.x-xTrans, 0, 0);
glTranslated(0, m_rotationCenter.y+yTrans, 0);
glTranslated(0, 0, m_rotationCenter.z+zTrans);
glRotated( xRot, 1.0, 0.0, 0.0 );
glRotated( yRot, 0.0, 1.0, 0.0 );
glRotated( zRot, 0.0, 0.0, 1.0 );
glTranslated(-m_rotationCenter.x+xTrans, 0, 0);
glTranslated(0, -m_rotationCenter.y-yTrans, 0);
glTranslated(0, 0, -m_rotationCenter.z-zTrans);
glTranslated( -xTrans, 0.0, 0.0 );
glTranslated( 0.0, yTrans, 0.0 );
glTranslated( 0.0, 0.0, zTrans);
可以这样写,效果完全一样:
glTranslated(m_rotationCenter.x, m_rotationCenter.y, m_rotationCenter.z);
glScalef( scale, scale, scale );
glTranslated(-xTrans, yTrans, zTrans);
glRotated( xRot, 1.0, 0.0, 0.0 );
glRotated( yRot, 0.0, 1.0, 0.0 );
glRotated( zRot, 0.0, 0.0, 1.0 );
glTranslated(-m_rotationCenter.x, -m_rotationCenter.y, -m_rotationCenter.z);
但是如果你想围绕一个点(m_rotationCenter)进行旋转,那么你必须改变指令的顺序。
注意,要绕轴旋转,您必须以这种方式平移对象,即旋转点位于原点 (0, 0, 0):
glTranslated(-m_rotationCenter.x, -m_rotationCenter.y, -m_rotationCenter.z);
旋转对象:
glRotated( xRot, 1.0, 0.0, 0.0 );
glRotated( yRot, 0.0, 1.0, 0.0 );
glRotated( zRot, 0.0, 0.0, 1.0 );
最后将旋转的物体移回原来的位置:
glTranslated(m_rotationCenter.x, m_rotationCenter.y, m_rotationCenter.z);
当然,这些指令必须以相反的顺序执行,因为像glTranslated 和glRotated 这样的操作定义了一个新矩阵并将其与当前矩阵相乘。
最终代码必须是:
glScalef( scale, scale, scale );
glTranslated(-xTrans, yTrans, zTrans);
glTranslated(m_rotationCenter.x, m_rotationCenter.y, m_rotationCenter.z);
glRotated( xRot, 1.0, 0.0, 0.0 );
glRotated( yRot, 0.0, 1.0, 0.0 );
glRotated( zRot, 0.0, 0.0, 1.0 );
glTranslated(-m_rotationCenter.x, -m_rotationCenter.y, -m_rotationCenter.z);
进一步我建议先进行缩放(代码中的最后),这样更容易定义像m_rotationCenter和xTrans这样的坐标,因为缩放不适用于此坐标。它应用于仅限型号:
// move the model to its location
glTranslated(-xTrans, yTrans, zTrans);
// rotate the model around `m_rotationCenter`
glTranslated(m_rotationCenter.x, m_rotationCenter.y, m_rotationCenter.z);
glRotated( xRot, 1.0, 0.0, 0.0 );
glRotated( yRot, 0.0, 1.0, 0.0 );
glRotated( zRot, 0.0, 0.0, 1.0 );
glTranslated(-m_rotationCenter.x, -m_rotationCenter.y, -m_rotationCenter.z);
// scale the model
glScalef( scale, scale, scale );