OpenGl 用 2 点 glRotated 绘制一个圆柱体

OpenGl draw a cylinder with 2 points glRotated

我想展示绘制一个从点 a 开始并指向的圆柱体 我认为关键在第一个 glRotated 中,但这是我第一次使用 openGL a 和 b 是 btVector3

glPushMatrix();
glTranslatef(a.x(), a.y(), a.z());
glRotated(0, b.x(), b.y(), b.z());
glutSolidCylinder(.01, .10 ,20,20);
glPopMatrix();

有什么建议吗??

旋转 0 度后,旋转没有任何作用。

您希望 axiz z 指向 b。 为此,您需要计算 z 轴 (0,0,1) 和 norm(b - a)(即 arccos(z dot norm(b - a)))之间的角度,并且您需要围绕 z 轴之间的叉积旋转该量和 b - a。您的矢量库应该已经实现了这些方法(点积和叉积)。

norm(x) 是 x 的规范化版本,长度为 1。

根据glutsolidcylinder(3) - Linux man page

glutSolidCylinder() draws a shaded cylinder, the center of whose base is at the origin and whose axis is along the positive z axis.

因此,您必须分别准备转换:

  • 将圆柱体的中心移动到原点(即(a + b)/ 2)
  • 旋转圆柱轴(即 b - a)成为 z 轴。

glRotatef()的用法好像被误解了,还有:

  • 第一个值是旋转角度,以度为单位
  • 第2、3、4个值为旋转轴的x、y、z。

这将导致:

// center of cylinder
const btVector3 c = 0.5 * (a + b);
// axis of cylinder
const btVector3 axis = b - a;
// determine angle between axis of cylinder and z-axis
const btVector3 zAxis(0.0, 0.0, 1.0);
const btScalar angle = zAxis.angle(axis);
// determine rotation axis to turn axis of cylinder to z-axis
const btVector3 axisT = zAxis.cross(axis).normalize();
// do transformations
glTranslatef(c.x(), c.y(), c.z());
if (axisT.norm() > 1E-6) { // skip this if axis and z-axis are parallel
  const GLfloat radToDeg = 180.0f / 3.141593f; 
  glRotatef(angle * radToDeg, axisT.x(), axisT.y(), axisT.z());
}
glutSolidCylinder(0.1, axis.length(), 20, 20);

我写了这段代码(使用我以前从未使用过的 btVector3 的文档)。因此,请对此持保留态度。 (可能需要调试。)

所以,请记住以下几点:

  1. 文档。没有提到 btVector3::angle() returns 角度是度数还是弧度——我假设是弧度。

  2. 写这样的代码时,我经常不小心翻转东西(例如旋转到相反的方向)。这样的东西,我一般都是在debug的时候修复的,上面的示例代码大概需要这个。

  3. 如果 (b - a) 已经沿着正或负 z 轴,则 (b - a) × (0, 0, 1) 将产生一个 0 向量。不幸的是,医生。 btVector3::normalize() 没有提到应用于 0 向量时会发生什么。如果在这种情况下抛出异常,则必须添加额外的检查。