Geometry 将三次bezier曲线转换为基数样条曲线并返回

Geometry 将三次bezier曲线转换为基数样条曲线并返回,geometry,2d,bezier,spline,Geometry,2d,Bezier,Spline,我读过很多文章,描述了如何将基数样条曲线或正则样条曲线转换为三次贝塞尔曲线,比如一条 是否有一种方法可以实现相反的操作,即将一组三次贝塞尔曲线转换为基数样条曲线?例如,我们知道每条曲线的端点都在样条曲线上 我要寻找的是一种在信息损失最小的情况下通过这两种表示进行往返的方法。理想情况下,解决方案应该是稳定的,因此从三次bezier=>基数样条=>三次bezier=>基数样条在第二次操作后应该得到相同(或几乎相同)的曲线。想象点B和E之间的三次曲线。 如果定义为带张力参数s的基数样条曲线,则这些点中

我读过很多文章,描述了如何将基数样条曲线或正则样条曲线转换为三次贝塞尔曲线,比如一条

是否有一种方法可以实现相反的操作,即将一组三次贝塞尔曲线转换为基数样条曲线?例如,我们知道每条曲线的端点都在样条曲线上


我要寻找的是一种在信息损失最小的情况下通过这两种表示进行往返的方法。理想情况下,解决方案应该是稳定的,因此从三次bezier=>基数样条=>三次bezier=>基数样条在第二次操作后应该得到相同(或几乎相同)的曲线。

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

Tb=s*(E-A
Te=s*(F-B

若曲线定义为贝塞尔曲线,则切线向量为

Tb=3*(C-b
Te=3*(e-D

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

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


--

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

Tb=s*(E-A
Te=s*(F-B

若曲线定义为贝塞尔曲线,则切线向量为

Tb=3*(C-b
Te=3*(e-D

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

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


--

进一步说明MBo的上述答案,贝塞尔->基数的公式是:

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

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

进一步完善MBo的上述答案,bezier->cardinal的公式为:

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

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

如果你不想考虑太多,这里有一个非常简单的方法。可以说,贝塞尔曲线实际上只是一条样条曲线。诀窍是简化样条曲线的说明:

一些java风格的。。。假设您有一个参数为drawSpline的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);
这可能是认识到你必须如何去做的最简单的方法。这确实比一些人说的要容易得多。然而,如果样条曲线有更多的节点,从样条曲线向后到贝塞尔曲线可能会有点棘手。不过,上述内容可能会提供一些方向


我希望这有帮助

以防你不想想想太多,这里有一个非常简单的方法。可以说,贝塞尔曲线实际上只是一条样条曲线。诀窍是简化样条曲线的说明:

一些java风格的。。。假设您有一个参数为drawSpline的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);
这可能是认识到你必须如何去做的最简单的方法。这确实比一些人说的要容易得多。然而,如果样条曲线有更多的节点,从样条曲线向后到贝塞尔曲线可能会有点棘手。不过,上述内容可能会提供一些方向


我希望这有帮助

有趣。这是否意味着包含张力参数s后,bezier曲线和基数样条曲线之间存在一一映射?任何三次样条曲线都存在一个带有bezier的一一映射。如果不直接应用张力参数(例如,s=1/2的Catmull Rom),则可能使用某种特定类型的基数样条曲线。是,确切地看起来,只要取Catmull Rom样条曲线的每四个点,就会返回原始的基数样条曲线。这是正确的吗?不,Catmull Rom样条线是基数样条线。这是否意味着包含张力参数s后,bezier曲线和基数样条曲线之间存在一一映射?任何三次样条曲线都存在一个带有bezier的一一映射。如果不直接应用张力参数(例如,s=1/2的Catmull Rom),则可能使用某种特定类型的基数样条曲线。是,确切地看起来,只要取Catmull Rom样条曲线的每四个点,就会返回原始的基数样条曲线。这是正确的吗?不,Catmull Rom样条曲线是基数样条曲线