我在 X,Y + Rotation 中有 2 个点,我需要计算一个贝塞尔样条曲线(二次贝塞尔曲线的集合),它可以平滑地连接这两个点。(见图)该点代表游戏中只能缓慢旋转的单位。所以从A点到B点,必须走很长的路。附图显示了一条相当夸张的弯曲路径,但你明白了。
我可以使用哪些公式来计算这样的贝塞尔样条曲线?
刚刚看到我误解了你的问题。由于您有起点和终点以及两个方向(切线),您不能使用单个三次 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;
我使用这个系统在我正在开发的游戏中插入相机路径,效果很好。
您可能知道,即使我们假设有 2 个控制点,也有无限的解决方案。
我找到了Smoothing Algorithm Using Bézier Curves,它回答了您的问题(请参阅开头的方程式)Bx(t)
:By(t)
B x (t) = (1-t) 3 P 1x + 3 (1-t) 2 t P 2x + 3 (1-t) t 2 P 3x + t 3 P 4x
B y (t) = (1-t) 3 P 1y + 3 (1-t) 2 t P 2y + 3 (1-t) t 2 P 3y + t 3 P 4y
P 1和 P 4是您的端点,P 2和 P 3是控制点,您可以沿着所需的角度自由选择。如果您的控制点r
与点 的角度为 θ (x, y)
,则该点的坐标为:
x' = x - r sin(θ)
y' = y - r cos(θ)
(根据你使用的坐标系统——我想我的标志是对的)。唯一的自由参数是r
,您可以随意选择。您可能想使用
r = α dist(P 1 , P 4 )
α < 1。
我不记得我在哪里得到它,但我一直在使用它:
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
是起点和终点之间沿路径的比率。