我有一个在顶点X1上有一个底座的物体(一个圆锥体)(圆锥体的圆心底部在X1上居中)并指向Oz。我想旋转它,所以它会指向给定的顶点X2。我尝试了很多组合,我做了很多计算仍然无法让它工作。如果你可以使用C ++ OpenGL函数glRotatef给出答案会很好,但是一般的答案也会受到赞赏。我现在正在锥体上尝试这个,但它应该适用于任何网格。
到目前为止,我有这个:
h1 = sqrt(pow(p2.y - p1.y, 2) + pow(p2.z - p1.z, 2));
h2 = sqrt(pow(p2.x - p1.x, 2) + pow(p2.z - p1.z, 2));
h3 = sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2) + pow(p2.z - p1.z, 2));
r.x = sign(p1.y-p2.y)*acos((p1.z-p2.z)/h1) * 180/M_PI;
r.y = sign(p1.x-p2.x)*acos((p1.z-p2.z)/h2) * 180/M_PI;
r.z = 0;
cone.SetPosition(p2);
cone.SetHeight(h3);
cone.SetRotation(r);
其中sign()就是它的名字,返回-1表示负数,1表示正参数。 Cone对象的绘图功能如下所示:
void drawCone()
{
glPushMatrix();
glTranslatef(pos.x, pos.y, pos.z);
glRotatef(rot.x, 1, 0, 0);
glRotatef(rot.y, 0, 1, 0);
glRotatef(rot.z, 0, 0, 1);
glColor3f(col.red, col.green, col.blue);
gluDisk(cone, 0, radius, 10, 10);
gluCylinder(cone, radius, 0, height, 10, 10);
glPopMatrix();
}
它不需要是一个高度优化的解决方案,只需一个工作的解决方案。
答案 0 :(得分:4)
如果我正确地理解了你的问题,你基本上想要沿着最短的球形路径将一个矢量旋转到另一个矢量上 - 这通常归结为瞄准。在一般情况下,这对于欧拉角来说有点痛苦。我有一些代码在某个地方完全用欧拉角进行一般目标,但它过于复杂 - 如果由于某种原因你必须用欧拉角来做这个我可以挖掘它。
但是你真正想做的事情,恕我直言,是使用四元数表示法。这让事情变得非常简单。您只需将要旋转的矢量和要旋转的矢量,并找到它们的叉积。这是您想要旋转的轴。然后找到两个矢量之间的角度 - 即您想要旋转的量。围绕某个轴旋转一定量是四元数最好的 - 如果你想旋转到一个指向与初始矢量完全相反方向的轴上,那么就会有一个奇点 - 但这是不可避免的,并且可能并不重要你在做什么。
编辑:在给定角度和轴的情况下直接计算旋转矩阵也不难。但是在每种情况下我都必须这样做,我必须能够在旋转帧之间进行插值。这就是我建议使用四元数的原因。如果您不必平滑插值,任何从轴和角度导出旋转的方法都可以。