我需要一种算法将闭合贝塞尔曲线(可能是自交叉)转换为二进制位图:0表示内部像素,1表示外部像素。我正在编写一个代码,需要在bezier曲线上实现一些操作,有人可以给我一些关于beziere的资源或教程吗?维基百科和其他人没有说任何关于优化,减法,联合,结插入和删除以及其他操作: - )
alt text http://www.imagechicken.com/uploads/1271001073057545100.jpg
答案 0 :(得分:4)
此paper by Charles Loop and Jim Blinn详细介绍了您的问题。
另一种选择是将贝塞尔曲线细分为线段,然后使用您最喜欢的多边形填充算法。
答案 1 :(得分:2)
我想补充说,曲面细分选项非常有效,并且效果非常好。按线段逼近贝塞尔曲线听起来是错误的,因为您认为输出看起来像多边形。诀窍是使线段足够短以使误差非常小(例如,小于1/10像素)。
这是我用来计算步长的公式,以确保最大误差(即线段与真实曲线的偏差)小于delta:
令(x1,y1),(x2,y2),(x3,y3),(x4,y4)为贝塞尔曲线的控制点,以像素坐标为单位.j
dd0 = square(x1-2*x2+x3) + square(y1-2*y2+y3); dd1 = square(x2-2*x3+x4) + square(y2-2*y3+y4); dd = 6*sqrt(max(dd0, dd1));
然后dd是曲线上二阶导数的最大值 - 因为三次方的二阶导数是一个线性函数,这个最大值必须出现在一个端点上。这里我使用square(x)作为x * x的缩写。
if (8*delta > dd) { epsilon = 1; } else { epsilon = sqrt(8*delta/dd); }
然后epsilon是你的步长:如果你选择t = 0时线段的端点,t = epsilon,t = 2 * epsilon,...,(和t = 1时的最后一个端点),那么线段将在原始曲线的增量范围内。
选择delta = 0.1,您将获得与原始曲线无法区分的位图输出。