旋转物体
我有一个物体(圆锥体),其底面位于顶点 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();
}
它不需要是一个高度优化的解决方案,只需一个可行的解决方案即可。
I have an object (a cone) with a base on a vertex X1 (the circle base of the cone has it's center on X1) and points to Oz. I would like to rotate it, so it would point to a given vertex X2. I tried many combinations, I made many calculations still can't get it working. It would be nice if you could give an answer using the C++ OpenGL function glRotatef, but a general answer would be also appreciated. I'm trying this on a cone now, but it should be working on any mesh.
So far I have this:
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);
Where sign() is what it's name, returns -1 for negative and 1 for positive parameter. And the drawing function of the Cone object looks like this:
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();
}
It doesn't need to be a highly optimized solution, just a working one.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果我正确理解你的问题,你基本上想沿着最短的球形路径将一个向量旋转到另一个向量上 - 这就是瞄准通常的归结。在一般情况下,这对于欧拉角来说有点痛苦。我在某处有一些代码,完全用欧拉角来实现总体目标,但它过于复杂 - 如果出于某种原因你必须用欧拉角来做到这一点,我可以把它挖出来。
但恕我直言,你真正想做的是使用四元数表示。这让事情变得非常简单。您只需获取要旋转的向量和要旋转的向量,然后找到它们的叉积即可。这就是您要围绕其旋转的轴。然后找到两个向量之间的角度 - 这就是您想要旋转的量。围绕某个轴旋转一定量是四元数最擅长的——如果你想旋转到与初始向量完全相反的方向的轴上,就会出现奇点——但这是不可避免的,并且对于你在做什么。
编辑:给定角度和轴直接计算旋转矩阵也不难。但在每种情况下,我都必须这样做,因为我必须能够在旋转框架之间进行插值。这就是为什么我建议使用四元数。如果您不需要平滑插值,则任何从轴和角度导出旋转的方法都可以。
If I understand your question correctly, you basically want to rotate one vector onto another along the shortest spherical path- that is what aiming generally comes down to. This turns out to be a bit painful to do with Euler angles, in the general case. I have some code somewhere that does a general aim at entirely with Euler angles, but it is overly complicated- if for some reason you have to do this with Euler angles I could dig it up.
But what you really want to do here, IMHO, is use a quaternion representation. That makes things very simple. You just take the vector you want to rotate onto and the vector you want to rotate, and find their cross product. That is the axis you want to rotate around. Then find the angle between the two vectors- that is the amount you want to rotate by. Rotating by a certain amount around a certain axis is what quaternions do best- there is a singularity if you want to rotate onto an axis that points in exactly the opposite direction from your initial vector though- but that's unavoidable, and might not matter much for what you are doing.
EDIT: It's also not that hard to calculate the rotation matrix directly given an angle and an axis. But in every case I've had to do this in I had to be able to interpolate between the rotational frames. That's why I suggest using quaternions. If you don't have to interpolate smoothly any method of deriving a rotation from an axis and angle will be fine.