计算贝塞尔样条曲线以从一个点到另一个点

发布于 2024-08-14 04:01:30 字数 290 浏览 10 评论 0原文

我在 X,Y + 旋转中有 2 个点,我需要计算平滑连接这 2 个点的贝塞尔样条线(二次贝塞尔曲线的集合)。 (见图)点代表游戏中只能缓慢旋转的单位。所以从A点到B点,必须走很长的路。附图显示了一条相当夸张的弯曲路径,但你明白了。

替代文本

我可以使用什么公式来计算这样的贝塞尔样条线?

I have 2 points in X,Y + Rotation and I need to calculate a bezier spline (a collection of quadratic beziers) that connects these 2 points smoothly. (see pic) The point represents a unit in a game which can only rotate slowly. So to get from point A to B, it has to take a long path. The attached picture shows quite an exaggeratedly curvy path, but you get the idea.

alt text

What formulas can I use to calculate such a bezier spline?

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

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

发布评论

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

评论(3

笨笨の傻瓜 2024-08-21 04:01:30

刚刚看到我误解了你的问题。你不能使用单个 三次 Hermite 样条 来代替,因为你有一个起点和终点以及两个方向(切线)?有任何额外的限制吗?

要计算起点和终点切线,只需使用起点和终点方向,并根据起点和终点之间的距离缩放它们(另外还有一些其他常数因子,例如 0.5,具体取决于您希望路径的弯曲程度)。:

p0 = startpoint;
p1 = endpoint;
float scale = distance(p0, p1);
m0 = Vec2(cos(startangle), sin(startangle)) * scale;
m1 = Vec2(cos(endangle), sin(endangle)) * scale;

我使用这个系统可以在我正在开发的游戏中插入相机路径,并且效果很好。

Just saw that I misunderstood your question. Couldn't you use a single cubic hermite splines instead since you have a start and end point and two directions (tangents)? Are there any additional constraints?

To calculate the start and end tangents just use the start and end direction and scale them with the distance between the start and end points (and additionally some other constant factor like 0.5 depending on how curvy you want the path to be).:

p0 = startpoint;
p1 = endpoint;
float scale = distance(p0, p1);
m0 = Vec2(cos(startangle), sin(startangle)) * scale;
m1 = Vec2(cos(endangle), sin(endangle)) * scale;

I use this system to interpolate camera paths in a game I'm working on and it works great.

剩一世无双 2024-08-21 04:01:30

您可能知道,即使我们假设有 2 个控制点,也有无限的解。

我发现 使用贝塞尔曲线的平滑算法,它回答了您的问题(请参阅开头的 Bx(t)By(t) 方程):

Bx(t) = (1-t)3 P1x + 3(1-t)2 t  P2x + 3 (1-t) t2 P3x + t3 P4x

B< sub>y(t) = (1-t)3 P1y + 3(1-t)2 t  P2y + 3 (1-t) t2 P3y + t 3 P4y

P1 和 P4 是您的端点,P2 和P3 是控制点,您可以沿着所需的角度自由选择。如果控制点与点 (x, y) 的距离为 r,且沿角度 θ,则该点的坐标为:

x' = x - r sin( θ)

y' = y - r cos(θ)

(根据您使用的坐标系 - 我认为我的符号是正确的)。唯一的免费参数是r,您可以根据需要选择。您可能想使用

r = α dist(P1, P4)

且 α 1.

As you probably know, there are infinite solutions, even if we assume 2 control points.

I found Smoothing Algorithm Using Bézier Curves, which answers your question (see equations of Bx(t) and By(t) in the beginning):

Bx(t) = (1-t)3 P1x + 3 (1-t)2 t  P2x + 3 (1-t) t2 P3x + t3 P4x

By(t) = (1-t)3 P1y + 3 (1-t)2 t  P2y + 3 (1-t) t2 P3y + t3 P4y

P1 and P4 are your endpoints, and P2 and P3 are the control points, which you're free to choose along the desired angles. If your control point is at a distance r along an angle θ from point (x, y), the coordinates of the point are:

x' = x - r sin(θ)

y' = y - r cos(θ)

(according to the co-ordinate system you've used—I think I got the signs right). The only free parameter is r, which you can choose as you want. You probably want to use

r = α dist(P1, P4)

with α < 1.

泪痕残 2024-08-21 04:01:30

我不记得我从哪里得到它,但我一直在使用这个:

Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
      float u = 1 - t; 
      float tt = t*t;
      float uu = u*u;
      float uuu = uu * u;
      float ttt = tt * t;

      Vector2 p = uuu * p0; //first term
      p += 3 * uu * t * p1; //second term
      p += 3 * u * tt * p2; //third term
      p += ttt * p3; //fourth term

      return p;
}

其中 t 是沿起点和终点之间的路径的比率。

I don't remember where I got it, but I have been using this:

Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3)
{
      float u = 1 - t; 
      float tt = t*t;
      float uu = u*u;
      float uuu = uu * u;
      float ttt = tt * t;

      Vector2 p = uuu * p0; //first term
      p += 3 * uu * t * p1; //second term
      p += 3 * u * tt * p2; //third term
      p += ttt * p3; //fourth term

      return p;
}

where t is ratio along path between start and end points.

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