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
的文档)。因此,请对此持保留态度。 (可能需要调试。)
所以,请记住以下几点:
文档。没有提到 btVector3::angle()
returns 角度是度数还是弧度——我假设是弧度。
写这样的代码时,我经常不小心翻转东西(例如旋转到相反的方向)。这样的东西,我一般都是在debug的时候修复的,上面的示例代码大概需要这个。
如果 (b - a) 已经沿着正或负 z 轴,则 (b - a) × (0, 0, 1) 将产生一个 0 向量。不幸的是,医生。 btVector3::normalize()
没有提到应用于 0 向量时会发生什么。如果在这种情况下抛出异常,则必须添加额外的检查。
我想展示绘制一个从点 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
的文档)。因此,请对此持保留态度。 (可能需要调试。)
所以,请记住以下几点:
文档。没有提到
btVector3::angle()
returns 角度是度数还是弧度——我假设是弧度。写这样的代码时,我经常不小心翻转东西(例如旋转到相反的方向)。这样的东西,我一般都是在debug的时候修复的,上面的示例代码大概需要这个。
如果 (b - a) 已经沿着正或负 z 轴,则 (b - a) × (0, 0, 1) 将产生一个 0 向量。不幸的是,医生。
btVector3::normalize()
没有提到应用于 0 向量时会发生什么。如果在这种情况下抛出异常,则必须添加额外的检查。