5

我有一个带有 2 个控制点的立方贝塞尔曲线。起点和控制点是已知的。需要得到曲线的所有点,给定控制点、起点和终点。我想要实现的是..给定一个从1到曲线长度的值i..获取该位置每个点的X和Y以及alpha(角度)。我找不到很好的参考或工作代码。我正在使用 JavaScript。

4

2 回答 2

19

如果我理解正确,您正在尝试确定贝塞尔曲线在每个点的位置和斜率(与曲线相切)。

假设您的起点是 (ax, ay),终点是 (dx, dy),控制点是 (bx, by) 和 (cx, cy)。

位置很容易。首先,计算混合函数。这些控制控制点在曲线上的“效果”。

B0_t = (1-t)^3
B1_t = 3 * t * (1-t)^2
B2_t = 3 * t^2 * (1-t)
B3_t = t^3

请注意当 t 为 0 时 B0_t 为 1(而其他一切都为零)。此外,当 t 为 1 时 B3_t 为 1(并且其他所有值都为零)。所以曲线从 (ax, ay) 开始,到 (dx, dy) 结束。

任何中间点 (px_t, py_t) 将由以下给出(将 t 从 0 变为 1,在循环内以小增量变化):

px_t = (B0_t * ax) + (B1_t * bx) + (B2_t * cx) + (B3_t * dx)
py_t = (B0_t * ay) + (B1_t * by) + (B2_t * cy) + (B3_t * dy)

坡度也很容易做到。使用https://stackoverflow.com/a/4091430/1384030中给出的方法

B0_dt = -3(1-t)^2
B1_dt = 3(1-t)^2 -6t(1-t)
B2_dt = - 3t^2 + 6t(1-t)
B3_dt = 3t^2

因此,x 和 y 的变化率为:

px_dt = (B0_dt * ax) + (B1_dt * bx) + (B2_dt * cx) + (B3_dt * dx)
py_dt = (B0_dt * ay) + (B1_dt * by) + (B2_dt * cy) + (B3_dt * dy)

然后用于Math.atan2(py_dt,px_dt)获取角度(以弧度为单位)。

于 2013-03-14T00:38:28.383 回答
4

De Casteljau 算法在数值上更稳定。在这里,它还有一个额外的优点,即它计算切线(因此,切角)作为计算点之前的步骤。

但是,它根据参数值而不是length工作。作为渲染曲线的一部分,最好通过参数而不是值来计算点。参数的范围将是[0 ... 1]0对应于1曲线的起点和终点。

于 2013-03-14T11:22:50.140 回答