论文网
English Papers
万事OK网
发表论文
 
 首页 > IT文章 > 程序设计 >
画直线算法

[科技论文网] http://www.scipapers.com    2007-12-01  

    画直线算法

    前段时间做了一下光栅直线生成算法的研究,并且在VC下实现了DDA算法、Bresenham算法、对称算法、两步算法、及四步算法。这里给个总结,希望和大家交流。 

     总述

           主要研究的算法主要有DDA算法、Bresenham算法、对称算法、两步算法、及四步算法,此外还对自适应多步位移码画线算法进行了一定研究。其中,DDABresenham算法都是单步画线算法,其它是多步画线算法。

     算法介绍

       DDA算法和Bresenham算法是经典的画线算法,并且业已证明Bresenham画线算法使用了最小的计算量,是最高效的单步画线算法,这里不再对其进行说明。以下对其余各个算法进行必要的说明。

    1 对称直线生成算法

           对称直线生成算法基于这样一个事实:直线以中点位界,其两边是对称的。因而可以利用这个对称性,对Bresenham算法进行改进,使得每进行一次判断就可以生成相对于直线中点的两个对称点。如此以来,直线就由两端向中间生成。算法用C++语言描述如下:

           int x1 = m_start.m_x;  // 起点x

        int y1 = m_start.m_y;  // 起点y

        int x2 = m_end.m_x;    // 终点x

        int y2 = m_end.m_y;    // 终点y

        int dx = m_end.m_x - m_start.m_x;

        int dy = m_end.m_y - m_start.m_y;

        int dx2 = dx << 1;

        int dy2 = dy << 1;

        int e  = dy2 - dx;  // 决策量

        int half = (dx+1) >> 1;

        for (int i=0; i<half; i++)

        {

           pDC->SetPixel(x1, y1, color);

           pDC->SetPixel(x2, y2, color);

           if (e > 0)  // e>0时,始端y向加1,末端y向减1

           {

               y1++;

               y2--;

               e -= dx2;

           }

           //始端x向加1,末端x向减1

           x1++;

           x2--;

           e += dy2;

        }

    2 两步算法

        两步画线算法每判断一次就生成两个点,这与对称算法相似,不同的是对称算法是从两端向中间进行的,而该算法是始终沿一个方向进行的,一次生成2个连续的点。当斜率k满足条件0k1时,考虑当前点P,如图1所示,直线与AB的交点一定落在AB区间的四等分中之一。

    1 下一待选点位置必在四个等分区间之一

           实际上,两个连续点可能出现的形式只有四种情况,即DDDXXDXX。其中X表示沿水平方向移动一个像素,D表示沿对角方向移动一个像素,见图2

    2 连续两点可能出现的4种形式

           决策量e的初值为e=4dy–dx,对于Pattern 1e的增量为4dy-4dx 对于Pattern 23e的增量为4dy-2dx;对于Pattern 4 e的增量为4dy算法用C++语言描述如下:

    int x = m_start.m_x;  // 起点x

        int y = m_start.m_y;  // 起点y

        int dx = m_end.m_x - m_start.m_x;

        int dy = m_end.m_y - m_start.m_y;

        int dx2 = dx << 1;

        int dy2 = dy << 1;

        int dx4 = dx2 << 1;

        int dy4 = dy2 << 1;

        int inc4 = dy4 - dx4;

        int inc2 = dy4 - dx2;

       

        int e = dy4 - dx;

        pDC->SetPixel(x, y, color);

        for (int i=0; i<dx; i+=2)

        {  

           if (e > dx)

           {

               // Pattern 4

               if (e > dx2)

               {

                  e += inc4;

                  x++;

                  y++;

                  pDC->SetPixel(x, y, color);

                  x++;

                  y++;

                  pDC->SetPixel(x, y, color);

               }

               // Pattern 3

               else

               {

                  e += inc2;

                  x++;

                  y++;

                  pDC->SetPixel(x, y, color);

                  x++;

                  pDC->SetPixel(x, y, color);

               }

              

           }

           else

           {

               // Pattern 2

               if (e > 0)

               {

                  e += inc2;

                  x++;

                  pDC->SetPixel(x, y, color);

                  x++;

                  y++;

                  pDC->SetPixel(x, y, color);

               }

               // Pattern 1

               else

               {

                  x++;

                  pDC->SetPixel(x ,y, color);

                  x++;

                  pDC->SetPixel(x, y, color);

                  e += dy4;    

               }

           }  

        }  

        每计算一次e值就生成两个点,从而提高画线效率,但是要进行较多的判断,所以效率提高并不明显。

    3 四步画线算法

        四步画线算法类似域两步画线算法,不同的时每判断一次,就生成四个点。如图3所示,直线一次前进四个点的情形。

    3 四步画线算法示意图

           对于四步画线算法,规的跟两步算法相似的表示方法,共有14种形式,如图4

    4 连续四点肯能出现的14种形式

           4中,自底向上依次是Pattern 1Pattern 14Pattern 1XXXXPattern 2XXXD,……,Pattern 14DDDD

           初始时,e=-dx Pattern 1e的增量为8dyPattern 2Pattern 4e的增量为8dy-2dxPattern 5Pattern 8e的增量为8dy-4dxPattern 9Pattern 13e的增量为8dy-6dxPattern 14e的增量为8dy-8dx。鉴于代码过长,这里不再给出。

    4 自适应多步位移码画线算法

           与传统的直线算法不同,自适应多步位移码画线算法首先将待绘制直线表达成一串由01组成的位移码,根据位移码的特点,自适应的确定一次生成的像素数目,从而获得更高的绘制效率。这里引入两个引理:

           引理1 设有从(x1, y1)到(x2, y2)的直线,0Hy2-y1Kx2-x1。那么在该直线的位移码中,相邻两个1之间连续0的数目w[(K-H)/H][K/H][A]表示对A取整。

        引理2设有从(x1, y1)到(x2, y2)的直线,0Hy2-y1Kx2-x1。那么在该直线的位移码中,相邻两个0之间连续1的数目w[H/(K-H)][K/(K-H)]

           证明略。

    这里给出自适应多步位移码画线算法的伪代码:

           K = x2 – x1;

           H = y2 – y1;

           T = [(K – 1)/2] – H;

           Divide(H, K – H, N, Tchg);

           x = x1;

           y = y1;

           WHILE x<= x2 DO

                  IF T<0 THEN

                         y = y +1;

                         xend = x+N;

                         WHILE x<xend Do

                                DrawPixel(x, y);

                                x = x +1;

                         END WHILE

                         T = T+Tchg;

                  ELSE

                         T = T – H;

                         DrawPixel(x, y);

                  END IF

                  x = x +1;

           END WHILE

           从理论而言,该算法根据直线斜率自适应地选择一个步长, 以一次判断生成多个采样点的方式对直线进行绘制,从而大大提供了绘制效率。但是实际上,连续两个10)中间01)的个数虽然只在两个整数上选择,但是到底在哪一步是哪一个难以判断,所以实现起来并不容易,而且目前尚未有解决方法。

     算法效率

     

    Bresenham

    对称

    两步

    四步

    加法

    1

    0.5

    1

    1

    比较

    2

    1

    1.5

    1.3

    加法和比较

    3

    1.5

    2.5

    2.3

    乘法

    2

    3

    4

    6

           上表给出平均每步所进行的加法次数和比较次数,乘除次数是整算法总共的次数。DDA算法未在表中给出,它与Bresenham相似,但使用了多次浮点乘除运算和取整运算,效率明显低于其它算法。Bresenham与其它算法相比,加法步骤相当(对称算法除外),但比较次数较多。理论上而言,后面的算法效率较高。但是应该注意到多步算法,如两步和四步算法,在进行循环之前要做很多的初始化工作,而且乘除次数大于Bresenham算法。在进行较短直线绘制时,效率反而不如Bresenham算法快。

    (一些算法的源程序较长,这里未给出。)

        来源:

声明:本文由网友推荐或作者提交,版权归原作者所有,刊登此文仅为传播知识,展示研究成果,提高文章引用率。未经原作者授权,禁止用于任何形式的商业行为。科技论文网倡导尊重知识、尊重劳动、保护原创、知识共享。由于部分论文文章来于网络,文章作者不祥,请相关的原创作者与我们联系,以便加上您的署名。

  
画直线算法
下面没有链接了     从一道笔试题谈算法优化
最新论文
·[程序设计]画直线算法
·[程序设计]从一道笔试题谈算法优化
·[程序设计]希尔排序源代码
·[程序设计]Dijkstra算法完整实现源代码
·[程序设计]二叉树删除以及DSW算法C源代码
·[程序设计]MSSQL树算法实现
·[程序设计]字符串搜索算法
·[程序设计]图论的基本算法
·[程序设计] 抛玻璃算法
·[程序设计]汉诺塔C源码
 
 

搜索论文

Google
论文分类

论文网 论文发表网 论文 免费论文网 找论文网 毕业论文 中国论文网 英语论文 百度论文 聘教网 易搜
 免费发布论文    中国论文网 2008版权所有  业务联系:pinjiao@126.com