沿3d中的Bézier路径移动对象:旋转问题

时间:2011-06-05 15:03:28

标签: opengl geometry rotation

在我的opengl应用程序中,我在3d空间中有一个Bézier曲线,我想沿着它移动一个对象。 旋转的一部分是好的:我在计算它们时遇到了一些问题。在我看来,管道应该是这样的:

  • 在Bézier(位置向量)上找到点
  • 找到正切,正常,副正常(自由网帧)
  • 找到切线矢量和x轴之间的角度
  • (正常和y轴以及副轴和z轴相同)
  • 推送矩阵
  • 平移位置,以角度旋转,绘制对象
  • pop matrix

但它并没有像我预期的那样:旋转似乎是随机的,并不遵循曲线。 有什么建议吗?

2 个答案:

答案 0 :(得分:4)

你会遇到Frenet框架的问题,因为不幸的是,当曲线偶然是直的时,它是不确定的 (具有消失的曲率),并且在点周围的方向上呈现出大的波动 密切平面的法线在方向上有重大变化,特别是在正常翻转的拐点处。

我建议使用称为Bishop框架的东西(你可以谷歌它,并找出如何在离散设置中计算它)。它也被称为平行传输帧或最小旋转帧 - 它的优点是始终定义帧,并以受控方式改变方向。

我不认为Frenet框架的问题必然会解释您遇到的问题。您应该从一些简单的测试用例开始 - 例如,限制在XY平面的贝塞尔曲线,并逐步完成计算,直到找到错误的为止。

答案 1 :(得分:2)

而不是计算角度,只需将框架推入模型视图矩阵即可。 Normal,Binormal和Tangent位于矩阵的左上角3x3,第4列的平移和4,4的元素是1.而不是Frenet帧使用已经提到的Bishop帧。所以在代码中:

// assuming you manage your curve in a (opaque) struct Bezier
struct BezierCurve;

typedef float vec3[3];

void bezierEvaluate(BezierCurve *bezier, float t, vec3 normal, vec3 binormal, vec3 tangent, vec3 pos);

void apply_bezier_transform(Bezier *bezier, float t)
{
    float M[16]; // OpenGL uses column major ordering
    // and this code is a excellent example why it does so:

   bezierEvaluate(bezier, t, &M[0], &M[4], &M[8], &M[12]);
   M[3] = M[7] = M[11] = 0.;
   M[15] = 1.;

   glMultMatrixf(M);
}