我有一个控制点数组,代表了一个贝塞尔曲线。这可能是一个五阶或一百阶的贝塞尔曲线,或者在它们之间的任何阶数。我正在寻找一种将该贝塞尔曲线简化为多个三次贝塞尔曲线的方法。下面的插图展示了如何将十度曲线简化为三度曲线,但我想进一步简化它,将其简化为几个三次贝塞尔曲线以达到更好的逼近效果。
代码示例将非常有帮助。
i = 0
e = points.length-4
curves = []
do {
crset = points.subset(i, 4)
curves.push(formCRCurve(crset))
} while(i++<e)
formCRCurve(points: p1, p2, p3, p4):
d_start = vector(p2.x - p1.x, p2.y - p1.y)
d_end = vector(p4.x - p3.x, p4.y - p3.y)
return Curve(p2, d_start, d_end, p3)
我们可以看到为什么需要这些虚拟点:在给定四个点的情况下,我们可以使用一些来自第一和第四个点的切线信息,从第二个点到第三个点形成一个Catmull-Rom曲线。
当然,我们实际上想要的是贝塞尔曲线,而不是Catmull-Rom曲线,但是因为它们是相同类型的曲线,所以我们可以在两者之间自由转换,因此:
i = 0
e = points.length-4
bcurves = []
do {
pointset = points.subset(i, 4)
bcurves.push(formBezierCurve(pointset))
} while(i++<e)
formBezierCurve(points: p1, p2, p3, p4):
return bezier(
p2,
p2 + (p3 - p1)/6
p3 - (p4 - p2)/6
p3
)
因此,基于点{p1,p2,p3,p4}的Catmull-Rom曲线,通过点p2
和p3
,可以写成等效的Bezier曲线,该曲线使用起始/控制1 /控制2 /结束坐标p2
,p2 + (p3-p1)/6
,p3-(p4-p2)/6
和p3
。
formCurve
函数中的 d_start
和 d_end
是做什么的?我应该用第二个函数替换第一个函数,还是应该以某种方式同时使用它们? (2) 我尝试实现这个,只使用了你最后一段提供的信息,但只有当我使用 p2 + (p3 - p1)/6
和 p3 - (p4 - p2)/6
时才得到合理的结果。请注意,我交换了 +
和 -
。我犯了错误还是你犯了错误? - mhelvens