我有一个表示Bezier曲线的控制点数组。它可能是五阶或100阶贝塞尔曲线,或者任何介于两者之间的曲线。我正在寻找一种将Bezier曲线简化为多个三次Bezier曲线的方法。下图显示了如何将十次曲线简化为三度曲线,但我想进一步将其简化为几个三次Bezier曲线,以获得更好的逼近效果。

代码示例将非常有用。
发布于 2015-05-25 04:09:53
正如mohsenmadi已经指出的那样:一般来说,如果不想出自己的错误度量,这是不可能做到的。另一个想法是“让我们把这条曲线近似成一系列低阶曲线”,这样我们就可以得到看起来更好的东西,而不是真正需要错误度量的东西。这有点像把曲线压平成线,除了用三次Bezier段代替线条,它给出了漂亮的曲线,同时保持了现代图形库的“可处理性”。
然后我们能做的是:把“100阶曲线”分解成一个三次Bezier序列,通过定期采样曲线,然后通过Catmull算法运行这些点。这个过程很简单:
t选择一些有规律的间隔值,如0,0.2,0.4,0.6,0.8和1,然后0开始并沿着其切线移动形成点n+1,并通过从n开始并遵循其切线形成一个点n+1。我们这样做是因为:0开始,以虚拟点n+1结束。让我们用图片来做这个。让我们从11阶Bezier曲线开始:

然后,让我们定期对其进行采样:

我们发明了第0和n+1st点:

然后我们运行Catmull程序:
i = 0
e = points.length-4
curves = []
do {
crset = points.subset(i, 4)
curves.push(formCRCurve(crset))
} while(i++<e)formCRCurve是做什么的?很好的问题:
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曲线,从点2到点3,利用从点1和点4得到的切线信息。
当然,我们实际上想要的是Bezier曲线,而不是Catmull曲线,但是因为它们是相同的“类”曲线,所以我们可以在两者之间自由转换,所以:
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曲线,通过点p2和p3,可以写成一个等价的Bezier曲线,它使用开始/控制1/control2 2/end协同处理p2、p2 + (p3 - p1)/6、p3 - (p4 - p2)/6和p3。
发布于 2015-05-24 03:59:19
首先,你必须知道没有近似的低度曲线会对你公平!你一定会引入错误,而不是逃避。问题是:如何近似使原始曲线和合成曲线在视觉上是相似的?
假设你原来的曲线是n度的,首先,细分它。你可以在不引入任何错误的情况下,任意细分一条曲线。在这里,每个细分的程度仍然是n,但几何复杂性和曲率率大大降低。第二,每个细分的降低程度,这是一个简单的形状,没有高曲率,会带来近似误差。
https://stackoverflow.com/questions/30419726
复制相似问题