在 3D 中沿贝塞尔路径移动对象:旋转问题



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

  • 在Bézier(位置向量)上查找点
  • 求切线、法线、二法线(frenet帧)
  • 求切线向量和x轴之间的角度
  • (法线和y轴以及副法线和z轴相同)
  • 推送矩阵
  • 在位置上平移,在角度上旋转,绘制对象
  • pop矩阵

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

Frenet框架会有问题,因为不幸的是,当曲线瞬间变直时,它是未定义的(具有消失的曲率),并且在围绕点的方向上表现出剧烈的摆动密切平面的法线在方向上有重大变化,尤其是在法线翻转的拐点处。

我建议使用Bishop框架(你可以在谷歌上搜索它,并了解如何在离散设置中计算它)。它也被称为平行运输框架或最小旋转框架——它的优点是框架总是被定义的,并且它以可控的方式改变方向。

我不认为Frenet框架的问题一定能解释你所面临的问题。你应该从一些简单的测试用例开始——例如,局限于XY平面的贝塞尔曲线,然后逐步进行计算,直到你发现问题所在。

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

// 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);
}

最新更新