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

Posted

技术标签:

【中文标题】在 3d 中沿贝塞尔路径移动对象:旋转问题【英文标题】:move object along a Bézier path in 3d: rotation problem 【发布时间】:2011-06-05 15:03:27 【问题描述】:

在我的 opengl 应用程序中,我在 3d 空间中有一条贝塞尔曲线,我想沿着它移动一个对象。 一切都可以作为旋转的一部分:我在计算它们时遇到了一些问题。在我看来,管道应该是这样的:

在贝塞尔曲线上找到点(位置向量) 求切线、法线、副法线(frenet 框架) 求切向量与 x 轴的夹角 (法线和y轴以及副法线和z轴相同) 推矩阵 平移位置、旋转角度、绘制对象 弹出矩阵

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

【问题讨论】:

【参考方案1】:

你会遇到 Frenet 框架的问题,因为不幸的是,当曲线甚至是暂时笔直时,它是未定义的 (具有消失的曲率),并且它在点周围的方向上表现出剧烈的波动 密切平面的法线方向发生重大变化的地方,尤其是在拐点处,法线翻转的地方。

我建议使用一种称为 Bishop 框架的东西(您可以在 Google 上搜索它,并了解如何在离散设置中计算它)。它也被称为平行传输框架或最小旋转框架 - 它的优点是框架始终被定义,并且以受控方式改变方向。

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

【讨论】:

感谢您的回答!我认为问题在于旋转,因为如果我绘制 3 个向量(正切法线副法线),它们似乎没问题。如果我用更简单的曲线(如螺旋线)代替贝塞尔曲线,问题仍然存在。顺便谢谢现在我会寻找主教框架【参考方案2】:

只需将框架推入模型视图矩阵,而不是计算角度。法线、副法线和切线在矩阵的左上角 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);

【讨论】:

hem.. 我不太明白你的回答:( @nkint:基本思想是,评估贝塞尔曲线会为您提供向量的正交基:法线、副法线和切线。变换矩阵就是这些基向量组合在一起。曲线上的位置是平移部分。我假设一些函数 bezierEvaluate (你可能命名它不同,但本质上它需要一个曲线和变化参数并吐出这 4 个向量)并将返回的向量直接传递给 OpenGL,中间没有中间角度计算。 +1 @nkint,把你的框架想象成三个正交的单位行向量 u,v,w。制作一个 3x3 矩阵 R,其行为 u,v,w。那么——对于表示x轴、y轴、z轴的行向量x=(1,0,0),y=(0,1,0),z=(0,0,1)—— xR=u,yR=v,zR=w。这应该可以帮助您看到 R 是将 xyz 轴带到框架 uvw 的旋转。这就是 OpenGL 矩阵的工作方式 - 所谓的列主要排序。

以上是关于在 3d 中沿贝塞尔路径移动对象:旋转问题的主要内容,如果未能解决你的问题,请参考以下文章

为啥开始的 mc 在贝塞尔补间时旋转

贝塞尔曲线

在 Unity 中沿其移动方向旋转对象

如何使用贝塞尔曲线沿路径为图像设置动画

pr蒙版贝塞尔曲线老是旋转

在OpenGL中沿对象后面的方向旋转相机