我有一个带有2个控制点的立方贝塞尔曲线。起点和控制点是已知的。给定控制,起点和终点,需要得到曲线的所有点。 我想要实现的是..给出从1到曲线长度的值i。得到该位置中每个点的X和Y以及alpha(角度)。 我找不到一个好的参考或工作代码。 我正在使用javascript。
答案 0 :(得分:16)
如果我理解正确,你试图确定Bezier的位置和斜率(曲线的切线)。
假设你的起点是(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)将由以下给出(从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)
获取角度(以弧度表示)。
答案 1 :(得分:4)
De Casteljau algorithm在数值上更稳定。这里有一个额外的好处,它计算切线(因此,切线角)作为计算点之前的步骤。
但是,它的工作原理是参数,而不是长度。作为渲染曲线的一部分,最好通过参数而不是值来计算点。参数的范围为[0 ... 1]
,0
对应于起点,1
为曲线的终点。
答案 2 :(得分:0)
这个库也可能会有所帮助。