码迷,mamicode.com
首页 > 编程语言 > 详细

计算机图形学(二)输出图元_3_画线算法_3_Bresenham画线算法

时间:2016-04-19 12:20:57      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:

Bresenham画线算法

    

本来在word中是有右下数的,一编辑在csdn中编辑就没有了。

            技术分享           技术分享       技术分享     技术分享 

     Bresenham画线算法是由Bresenham提出的一种精确而有效的光栅线生成算法,该算法仅仅使用增量整数计算。另外Bresenham算法还可用于显示圆和其他曲线。图3.8和图3.9给出了绘制线段的屏幕局部。垂直轴表示扫描线位置,水平轴标识像素列。在这个例子中,我们以单位x间隔取样,并且需要确定每次取样时两个可能的像素位置中的哪一个更接近于线路径。从图3.8中的左端点开始,需要确定下一个取样像素位置是(11, 1l)还是(1 1, 12)。类似地,图3.9则给出了像素位置(50,50)为左端点的具有负斜率的线段。此时,需要确定下一个像素位置是((51, 50)还是((51, 49)。为了解决这些问题,Bresenham算法将对整型参数的符号进行检测,整型参数的值正比于两像素与实际线段之间的偏移。

技术分享
    为了说明Bresenham方法,首先考虑斜率小于1的直线的扫描转换过程,沿线路径的像素位置由以单位x间隔的取样来确定。从给定线段的左端点(xo,yo)开始,逐步处理每个后继列(x位置),并在其扫描线y值最接近线段的像素上绘出一点:图3.10显示了这个过程的第k步。假如已经决定要显示的像素在(xk ,yk),那么下一步需要确定在列Xk+1 = Xk+1上绘制哪个像素,是在位置(xk+1 , yk) ,还是位置(xk+1,yk+1) 

技术分享

技术分享


    在取样位置xk+1,我们使用dlower和dupper,来标识两个像素与数学上线路径的垂直偏移(参见图3.11),在像素列位置xk +1处的直线上的y坐标可计算为
技术分享

那么

技术分享

技术分享

要确定两像素中哪一个更接近线路径,需要测试这两个像素偏移的差:
技术分享

通过重新安排等式(3.13)可获得画线算法第k步的决策参数pk,从而仅使用整数进行计算。
设△y和△x分别为两端点的垂直和水平偏移量,令m = △y/△x,将决策参数定义为
技术分享

pk的符号与dlower - dupper,的符号相同(因为例子中△x >0),参数c是一常量,其值为2△y + △x (2b-1),它与像素位置无关,且会在循环计算pk时被消除。假如yk处的像素比yk+ 1的像素更接近于线段(即dlower < dupper),那么参数pk是负的。此时,绘制下面的像素;反之,绘制上面的像素。

    直线上的坐标会沿x或y方向的单位步长而变化。因此,可以利用递增整数运算得到后继的决策参数值。在k+1步,决策参数可以从等式(3.14)计算得出:

技术分享
将上述方程减去等式(3.14),可以得到

技术分享
但是xk+1 = xk+1,因而得到

技术分享
其中,yk+1-yk取0或1,取决于参数pk的符号。
    决策参数的递归运算在线段的坐标端点开始的每个整数x位置进行,起始像素位置(xo,yo)的第一个参数po通过等式(3.14)及m = △y/△x计算得出 
技术分享

    我们可以将正斜率小于1的线段的Bresenham画线算法概括为以下步骤。常遗2△y和2△y-2△x对每条进行扫描转换的直线只计算一次,因此该系统仅进行这两个常量之间的整数加减法。
:
|m| < 1时的Bresenham画线算法
1.输人线段的两个端点,并将左端点存储在(xo,yo)中;
2.将(xo,yo)装入帧缓存,画出第一个点;

3.计算常量△x 、△y 、2△y和2△y-2△x,并得到决策参数的第一个值:

技术分享

4.从k=0开始,在沿线路径的每个xk处,进行下列检测:

如果pk<0,下一个要绘制的点是(xk+1,yk+1),并且

技术分享

5.重复步骤4, xk-1
技术分享

例3.1  Bresenham画线算法
为了演示上述算法,我们绘制这样一条线段:端点为(20, 10)和(30,18)该线段的斜率为0.8且
技术分享

那么初始决策参数数的值为

技术分享

计算后续决策参数的增量为

技术分享

技术分享

图3.12中给出了沿这条线路径生成的像素点。

技术分享

       下列程序中给出了斜率为0 < m < 1.0的Bresenham画线算法的实现。首先将线段的端点像素位置输入程序,然后从左端点到右端点绘制像素。

#include<stdlib.h>
#include<math.h>

/*Bresenham line-drawing procedure for |m|<1.0. */
void lineBres(int x0,int y0,int xEnd,int yEnd)
{
    int dx = fabs(xEnd - x0),dy = fabs(yEnd - y0);
    int p = 2*dy - dx;
    int twoDy = 2*dy, twoDyMinusDx = 2*(dy - dx);
    int x,y;

/*Determine which endpoint to use as start position.*/
if(x0 > xEnd){
    x = xEnd;
    y = yEnd;
    xEnd = x0;
}
else{
    x = x0;
    y = y0;
}
setPixel(x,y);
while(x<xEnd){
  x++;
if(p < 0)
  p += twoDy;
else{
  y++;
  p += twoDyMinusDx;
}
  setPixel(x,y);
}

}

        通过考虑xy平面各种八分和四分区域间的对称性,Bresenham算法对任意斜率的线段具有通用性。对于斜率为正值且大于1.0的线段,只要交换x和y方向的规则,即沿y方向以单位步长移动并计算最接近线路径的连续x值。当然,也可以改变程序,使之能从任何端点开始绘制像素,假如正斜率线段的初始位置是右端点,那么在从右至左的步进中,x和y都将递减。为了确定无论从任何端点开始都能绘制相同的像素,当候选像素相对于线段的两个垂直偏移相等时dlower  =  dupper,我们总是选择其中较高(或较低)的像素。对于绘制负斜率的线段,除非一个坐标递减而另一个递增,否则程序是类似的。最后,可以分别处理下列特殊情况:水平线(△y = 0)、垂直线(△x = 0)和对角线|△x| = |△y|,它们都可直接装入帧缓存而无需进行画线算法处理。

计算机图形学(二)输出图元_3_画线算法_3_Bresenham画线算法

标签:

原文地址:http://blog.csdn.net/heyuchang666/article/details/51178207

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!