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

发布于 2024-11-12 22:55:39 字数 317 浏览 5 评论 0原文

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

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

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

in my opengl application i have a Bézier curve in 3d space and i want to to move an object along it.
everything it's ok a part of rotations: i have some problem in calculating them. in my mind the pipeline should be this:

  • find point on the Bézier (position vector)
  • find tangent, normal, binormal (frenet frame)
  • find the angle between tangent vector and x axis
  • (the same for normal and y axis and binormal and z axis)
  • push matrix
  • translate in position, rotate in angles, draw object
  • pop matrix

but it does not go as i expected: the rotations seems to be random and does not follow the curve.
any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鱼窥荷 2024-11-19 22:55:39

Frenet 框架将会出现问题,因为不幸的是,即使曲线暂时是直的,它也是不确定的
(曲率消失),并且它在点周围的方向上表现出剧烈的波动
密切平面法线方向发生重大变化的地方,尤其是在法线翻转的拐点处。

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

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

You're going to have problems with the Frenet frame, because, unfortunately, it is undefined when the curve is even momentarily straight
(has vanishing curvature), and it exhibits wild swings in orientation around points
where the osculating plane’s normal has major changes in direction, especially at inflection points, where the normal flips.

I'd recommend using something called a Bishop frame (you can Google it, and find out how to compute it in a discrete setting). It is also referred to as a parallel transport frame or a minimum rotation frame - it has the advantage that the frame is always defined, and it changes orientation in a controlled way.

I don't think the problems with Frenet frames necessarily explain the problems you are having. You should start with some easy test cases - Bezier curves that are confined to the XY plane, for example, and step through your calculations until you find what's wrong.

梦罢 2024-11-19 22:55:39

无需计算角度,只需将框架推入模型视图矩阵即可。法线、副法线和切线位于矩阵的左上角 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);
}

Instead of computing angles just push the frame into the modelview matrix. Normal, Binormal and Tangent go in the upper left 3x3 of the matrix, translation in the 4th column and element 4,4 is 1. Instead of Frenet frame use the already mentioned Bishop frame. So in code:

// 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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文