2013-03-13 59 views
4

我有一个具有2个控制点的三次贝塞尔曲线。起点和控制点是已知的。在给定控制点,起点和终点的情况下,需要获得曲线的所有点。 我想要实现的是给定一个从1到曲线长度的值。获得每个点在该位置的X和Y以及alpha(角度)。 我找不到一个很好的参考或工作代码。 我使用的是javascript。在javascript中查找三次贝塞尔曲线的所有点

+0

那里寻找:http://stackoverflow.com/questions/4089443/find-the-tangent-of-a-point-on-a-cubic-bezier-curve-on-an-iphone – XDnl 2013-03-13 22:46:48

回答

15

如果我理解正确,您正试图确定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)得到角(弧度)。

4

De Casteljau algorithm更具数值稳定性。这里还有一个额外的好处,就是它可以计算切点(即切线角度)作为计算该点前的步骤。

但是,它按照参数值工作,而不是长度。作为绘制曲线的一部分,最好按参数计算点数,而不是数值。参数的范围将分别为​​,0对应的起始点和1曲线的终点。

+2

是的,它有三个优点。 *适用于任何程度的样条,无需修改。 *它不需要电源功能。 *最有价值的是结果具有参数“t”的切线和点,因此,对于需要解析公式在计算上更简单的情况。 – divanov 2013-04-03 20:07:02