直线的光栅化算法

  给定起点clip_image002[4]和终点clip_image004[4],直线的光栅化算法要找出哪些像素应该被着色。简单起见,这里假设clip_image006[4]

一、直观的方法

       当直线的斜率clip_image008[4]时,直线在clip_image010[14]向的变化速率小于在clip_image012[12]方向上的变化速率,因此可以遍历clip_image014[4]clip_image016[4]间的每一个clip_image012[13],计算对应的clip_image010[15]值并将其四舍五入画点。算法伪代码如下:

k = (y2 - y1) / (x2 - x1)
y = y1
for x = x1 to x2
    draw_point(x, round(y))
    y += k

而当clip_image018[4]时,必须交换clip_image012[14]clip_image010[16]的地位——遍历clip_image010[17]的取值,每次迭代计算对应的clip_image012[15]

二、Bresenham算法

       假设clip_image020[4],每当clip_image022[4]时,对应的要绘制点的clip_image010[18]坐标要么保持不变,要么增加1或减小1(简单起见,这里假设clip_image024[4],即只可能不变或增加1)。我们需要给出一个判断条件,判断什么时候该增加1、什么时候该保持不变。

       常见的方法是使用中点进行比较(有一种所谓“中点画线法”,其原理和Bresenham算法本质上是相同的)。假设保持不变时绘制的点坐标为clip_image026[4],那么clip_image010[19]增加1时坐标应为clip_image028[4],容易知道连接这两个点的线段的中点为clip_image030[6]。现假设直线与clip_image032[4]的交点坐标为clip_image034[4],那么就可以将clip_image030[7]与之比较——若clip_image036[4],就保持不变,否则增加1。这样判断的结果是我们总是选择离精确点更近的那个像素进行着色。

       由于每一轮迭代中clip_image012[16]的增量都是1,因此clip_image038[4]的增量是clip_image040[6]。我们维护一个变量clip_image042[10],表示clip_image044[4]的值。每次迭代clip_image042[11]都减小clip_image040[7],一旦发现clip_image042[12]小于零,就意味着应当使clip_image046[4]增加1,对应地clip_image042[13]的值也要加1。算法伪代码如下:

 

k = (y2 - y1) / (x2 - x1)
d = 0.5
n = y1
for m = x1 to x2
    draw_point(m, n)
    d -= k
    if(d < 0.0)
        n += 1
        d += 1

  更进一步地,可以通过用(x2 - x1)与之相乘的方法来消除上面的算法中与d有关的浮点操作,这样就彻底消灭了浮点运算而仅剩对整数的操作。即:

2_delta_y = 2 * (y2 - y1)
2_delta_x = 2 * (x2 - x1)
d = x2 - x1
n = y1
for m = x1 to x2
    draw_point(m, n)
    d -= 2_delta_y
    if(d < 0)
        d += 2_delta_x
        n += 1

 

posted on 2017-01-07 01:48  AirGuanZ  阅读(1168)  评论(0编辑  收藏  举报

导航