我正在编写一个程序,它将沿样条曲线绘制一个实体。我正在使用visual studio 2005,并使用C ++编写OpenGL。我正在使用FLTK打开我的窗口(快速和轻便的工具包)。
我目前有一种算法可以在给定一组控制点的情况下绘制一个基数三次样条曲线,方法是将这些点之间的间隔分成子区间并在这些子点之间绘制内容。子间隔的数量是可变的。
线条图代码运行得非常好,基本上如下工作:我使用样条曲线方程沿样条曲线生成一组点并将它们存储在一个数组中(作为一个称为Pnt3f的特殊数据结构,其中坐标是3个浮点数并且有一些方便的功能,如距离,长度,点和交叉产品)。然后我有一个循环遍历点数组并按如下方式绘制它们:
glBegin(GL_LINE_STRIP);
for(pt = 0; pt<=numsubsegements ; ++pt) {
glVertex3fv(pt.v());
}
glEnd();
如前所述,此代码效果很好。现在我想要做的是,而不是画一条线,我想挤出一个实体。我目前的探索是使用“圆柱”二次曲线沿线创建一个管。这有点棘手,因为我必须在我想要绘制圆柱体的方向上定向openGL。我的想法是这样做:
伪码:
Push the current matrix,
translate to the first control point
rotate to face the next point
draw a cylinder (length = distance between the points)
Pop the matrix
repeat
我的问题是得到点之间的角度。我只需要偏航和俯仰,滚动并不重要。我知道将两点的点积的弧余弦除以两点的大小,将返回它们之间的角度,但这不是我可以提供给OpenGL旋转的东西。我已经尝试在2d中执行此操作,使用XZ平面获得x旋转,并从原点创建点矢量,但它不会返回正确的角度。
我目前的做法要简单得多。对于每个旋转平面(X和Y),通过以下方式找到角度:
arc-cosine(('x'值的差异)/点之间的距离)
“x”值取决于你如何设置你的飞机,但是对于我的计算,我总是使用世界x。
除非有一些问题让它在我尚未解决的正确象限中绘制,我想得到建议,看看这是否是一个好的实现,或者看看是否有人知道更好的方法。
答案 0 :(得分:1)
一些注意事项:
首先,这个:
for(pt = 0; pt<=numsubsegements ; ++pt) {
glBegin(GL_LINE_STRIP);
glVertex3fv(pt.v());
}
glEnd();
不是绘制任何东西的好方法。每个glBegin()必须有一个glEnd()。你可能想让glBegin()退出循环。事实上,这是真正的运气。
第二件事
我目前的探索是使用a '圆柱'二次曲线创造一个管 沿着这条线
这将无法正常工作。'圆柱'二次曲面有一个平底座和一个平底座。即使你成功地根据花键进行正确的旋转,平顶的边缘也会从你想要的管的体积中弹出,并且它将不会平滑。您可以使用笔和纸在2D中进行尝试。尝试使用较短的扁平底座管来绘制光滑的管。这是不可能的。
第三,对于你的实际问题,这种轮换的权威工具是quaternions。在这个范围内解释起来有点复杂,但你可以在任何地方找到充足的信息 如果您使用过QT而不是FLTK,那么您也可以使用libQGLViewer。它有一个集成的Quaternion类,可以为您节省实现。如果您仍有选择,我强烈建议您转到QT。
答案 1 :(得分:1)
从两个相邻线段中的三个点形成两个矢量然后使用点积的反余弦来获得它们之间的角度是正确的。要使用此角度,您需要确定应围绕其旋转的轴。取相同两个向量的叉积来得到这个轴。然后,您可以使用此轴角度build a transformation matrix或将其作为参数传递给glRotate。
答案 2 :(得分:0)
您考虑过gluLookAt
了吗?将您的控制点作为眼点,将下一个点作为参考点,并使向上矢量垂直于两者之间的差异。