将三次贝塞尔曲线转换为基数样条曲线并返回

时间:2015-07-07 16:23:13

标签: geometry 2d bezier spline

我读过许多描述如何将基数或规范样条曲线转换为三次贝塞尔曲线的文章,例如this一条。

有没有办法反过来,即将一组三次贝塞尔曲线转换为基数样条曲线?例如,我们知道每条曲线的端点都在样条曲线上。

我正在寻找的是一种以最小的信息损失往返于两个表示的方法。理想情况下,解决方案应该是稳定的,因此从立方贝塞尔=>基数样条=> cubic bezier =>在第二次操作后,基数样条曲线应该产生相同(或几乎相同)的曲线。

3 个答案:

答案 0 :(得分:4)

想象一下B点和E点之间的三次曲线 如果将其定义为具有张力参数s的基数样条,则这些点中的切向量为

T b = s *( E - A
T e = s *( F - B

如果曲线定义为贝塞尔曲线,则切线矢量为

T b = 3 *( C - B
T e = 3 *( E - D

如果曲线BE相同,则切线的值相等,如果A,B,E,F,s已知,我们可以找到Bezier的控制点。反之亦然 - 如果B,C,D,E,s已知,我们可以找到基数样条的A,F点。例如,Bezier的第一个控制点是

C = B + s *( E - A )/ 3

enter image description here -

答案 1 :(得分:0)

进一步讨论MBo上面的答案,bezier的公式 - >红衣主教是:

A = E - (C - B)* 3 / s
F =(E-D)* 3 / s + B

答案 2 :(得分:0)

如果您不想过多考虑它,这是一种超级简单的解决方法。可以这么说,贝塞尔曲线实际上只是花键的一部分。诀窍是简化样条线的说明:

某些Java样式...说您有一个带有参数drawSpline(int degree,double [] controlPoints,double []结)的drawSpline函数;

立方:

 double controlPoints[] = {start.x, start.y, handleA.x, handleA.y, handleB.x, handleB.y, end.x, end.y};
 double knots[] = {0,0,0,0,1,1,1,1};
 drawSpline(3, controlPoints, knots);

二次方:

double controlPoints[] = {start.x, start.y, handle.x, handle.y, end.x, end.y};
double knots[] = {0,0,0,1,1,1};
drawSpline(2, controlPoints, knots);

这可能是识别您可能必须要做的最简单的方法。它确实比某些听起来容易得多。但是,如果样条线有更多的结,从样条线向贝塞尔曲线倒退可能会有些棘手。不过,以上内容可能会提供一些指导。

希望对您有所帮助!