Xiaolin Wu 算法中的端点计算是做什么的?

What is the endpoint calculation in the Xiaolin Wu algorithm doing?

Xiaolin Wu algorithm 在两点之间绘制一条抗锯齿线。这些点可以是亚像素,即非整数坐标。我假设 reader 熟悉该算法并且只记得重要的功能。我们遍历这条线的主要(较长)轴,假设它是 x 轴,基本上是逐列进行。在每一列中,我们为两个像素着色。计算等同于:在 x 坐标为给定像素列中心的点上在线上放置一个 1x1 正方形。我们称它为 S。如果我们将每个像素视为平面中的 1x1 正方形,我们现在计算 S 与它跨越的两个像素中的每一个之间的交叉区域,并将这些区域用作为每个像素着色的强度.

这很清楚,但是端点的计算是怎么回事?因为端点可以位于非整数位置,所以必须将它们视为特殊情况。这是来自链接的维基百科文章的伪代码,用于处理第一个端点 x0, y0:

// handle first endpoint
xend := round(x0)
yend := y0 + gradient * (xend - x0)
xgap := rfpart(x0 + 0.5)
xpxl1 := xend // this will be used in the main loop
ypxl1 := ipart(yend)
plot(ypxl1,   xpxl1, rfpart(yend) * xgap)
plot(ypxl1+1, xpxl1,  fpart(yend) * xgap)

我编辑掉了if (steep)条件,所以这是直线斜率小于1时的代码。rfpart1-fpartfpart 是小数部分。 ipart是整数部分。

我只是不知道这个计算应该做什么,而且我在网上找不到任何解释。我可以看到 yendxend 上方直线的 y 坐标,而 xend 是起点 (x0, y0) 所在像素的 x 坐标。为什么我们还要计算 yend?就好像我们正在延长线直到最近的整数 x 坐标。

我意识到我们正在使用特定强度为端点所在的像素以及紧靠其上方或下方的像素着色。我只是不明白这些强度来自哪里背后的逻辑。

利用吴晓林算法(以及一般的亚像素渲染技术),我们将屏幕想象成一个连续的几何平面,每个像素是该平面的一个 1x1 正方形区域。我们将像素的中心识别为具有整数坐标的点。

首先,我们找到线的所谓“长轴”,即线最长的轴。假设它是 x 轴。现在,我们遍历线条穿过的每个一像素宽的列。对于每一列,我们找到该列 center 线上的点,即 x 轴为整数。我们想象有一个 1x1 的正方形以该点为中心。该正方形将完全填满该列的宽度,并将与两个不同的像素重叠。我们根据正方形和像素之间重叠的 区域 为每个像素着色。

对于端点,我们做的事情略有不同:我们仍然以线与柱的中心线相交的地方为中心绘制一个正方形,但是我们将该正方形切掉在直线端点的水平方向上。如下图所示。

这是四个像素的放大视图。黑色十字代表这些像素的中心,红线是我们要画的线。红圈(x0, y0)是线的起点,线应该从那个点向右延伸。

您可以看到以红色十字为中心的灰色方块。每个像素将根据与这些正方形重叠的区域进行着色。但是,在左侧列中,我们在 x 坐标 x0 处截断了正方形。浅灰色可以看到整个正方形,但只有深灰色的部分用于面积计算。可能还有其他方法可以处理端点,例如我们可以将深灰色区域向上移动一点,使其垂直居中于 y 坐标 y0。大概它不会产生太大的明显差异,并且这在计算上是有效的。

我已经使用维基百科上伪代码中的变量名称对绘图进行了注释。

该算法在端点处是近似的。这是合理的,因为精确的计算将相当复杂(并且取决于端点的类型),因为结果几乎不可察觉。重要的是沿线段的别名。