-1

我想展示一个从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();

有什么建议么 ??

4

2 回答 2

0

由于您旋转 0 度,因此您的旋转不会做任何事情。

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

norm(x) 是 x 的标准化版本,长度为 1。

于 2018-02-15T09:27:03.673 回答
0

根据glutsolidcylinder(3) - Linux 手册页

glutSolidCylinder() 绘制一个带阴影的圆柱体,其底面的中心位于原点,其轴沿正 z 轴。

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

  • 将圆柱体的中心移动到原点(即 ( 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()返回角度是度数还是弧度——我假设是弧度。

  2. 在编写这样的代码时,我经常会不小心翻转一些东西(例如旋转到相反的方向)。这样的事情,我通常在调试中修复,对于上面的示例代码,这可能是必要的。

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

于 2018-02-15T09:36:07.990 回答