绘制锯齿状的、像素完美的1像素样条线(特别是Catmull-Rom算法)

8
简要背景:我正在开发一个基于Web的绘图应用程序,需要绘制通过其控制点的1像素粗的样条曲线。
我遇到的问题是,我需要将p1和p2之间的每个像素绘制为使用1像素铅笔工具一样。因此,不进行抗锯齿处理,一个像素一个像素地绘制。由于我的画笔系统依赖于将像素坐标应用于画布,因此必须手动完成此操作,而不能使用任何线/曲线库代码。
基本上,我需要将Bresenham算法中的一个像素步进与Catmull-Rom方程返回的坐标相结合。我遇到麻烦是因为Catmull-Rom点不是均匀分布的(因此我不能只说在曲线中应该有100个像素并运行方程100次)。我尝试使用X和Y增量的最大估计起始值,并使用Bresenham填充空隙,但由于四舍五入,我仍然会得到一些“脏”部分(即线明显向上和向右移动,但我仍然会得到两个具有相同Y分量的像素,导致线的“肥”部分)。
我确定这个问题已经解决了,因为几乎所有绘制样条曲线的图形程序都必须支持我需要的干净像素曲线。经过相当多的数学研究,我有点困惑,仍然没有解决方案。有什么建议吗?
编辑:这是一个我可能要渲染的曲线示例:
使用Catmull-Rom样条曲线方程,我们需要四个点来创建一个段。P0和P3用作P1->P2段的进出方向的切线。使用Catmull-Rom样条曲线,蓝色部分是在t从0到1移动时得到插值的全部内容。可以复制P0和P3以确保渲染绿色部分,因此对我来说这不是问题。
为了简单起见,我需要在P1和P2之间绘制曲线上的像素,假设我有形式为P0和P3的切线。我不一定需要使用Catmull-Rom样条曲线,但它们似乎是正确的工具,因为必须通过控制点。
编辑2:这是我所说的结果曲线不干净时的示例:
红色箭头指出了一些不应该有像素的位置。这是因为计算得到的坐标的X和Y分量变化率不同。因此,当每个分量被舍入(以获得精确的像素位置)时,可能会出现X或Y没有增加的情况,因为计算得到的坐标是(42.4999, 50.98)。将舍入换成floor或ceil并不能解决问题,因为它只会改变问题发生的位置。

如果您能添加另一张图,展示从P1到P2的预期结果,那就太好了。 - Dr. belisarius
@belisarius 我没有计算出根据Catmull-Rom方程哪些像素会被填充,但第二张图片应该能让您了解我想要实现的目标。 - Xenethyl
由于您的评论,我请求它:_但我仍然获得具有相同Y分量的两个像素_。 - Dr. belisarius
@belisarius 已经理解。我能够理解那个评论可能会让人感到困惑。如果没有看到我当前实现的问题,很难解释清楚,因此我附上了另一张图片。第三张图片是从我的应用程序中放大到400%的。红色箭头表示不应存在的像素(Y分量中的小数部分足够小,以至于不会被四舍五入)。 - Xenethyl
1个回答

2

感谢提供论文链接。我在搜索时没有包括“弧长”。我又进行了一些搜索,找到了更好的结果(请参见http://www.actionscript.org/forums/showthread.php3?t=213252)。似乎解决这个问题的被接受的方案很大程度上依赖于近似和预计算。由于这是在JavaScript中完成的,这可能会带来性能问题。我可能会重新发布我的问题,但目前感谢您的帮助。您确实指引了我正确的方向。 - Xenethyl
@Xenethyl 很高兴能帮忙!希望你能为你的场景进行优化。 - Dr. belisarius

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接