精华内容
下载资源
问答
  • 多边形填充

    2012-05-04 16:55:06
    多边形填充 计算机图形学 c++ 代码加文档
  • 多边形填充算法

    2018-12-10 19:51:10
    具体代码实现在conversionview.cpp中,实现多边形填充算法
  • c#实现多边形填充

    2021-03-16 00:37:43
    c#多边形填充源码实例,其中LCDEmulator_SE目录内的是程序要用到的一个控件的源码。  本C#多边形图形填充程序分为矢量填充和位图填充(区域填充)。矢量填充用的是扫描线算法,区域填充也是一种扫描线算法(而不是...
  • c语言多边形填充

    2016-09-13 21:02:23
    c语言多边形填充,快速填充法。 自己修改图像数组即可使用。
  • 多边形填充软件

    2014-06-01 23:22:10
    本软件利用MFC单文档开发了多变形填充软件,模拟计算机图形学中的多边形填充问题。
  • 计算机图形学的经典 学图形学的必看 不然后悔
  • 实验四 多边形填充算法 一名称多边形填充扫描算法 二算法分析 矩形是多边形扫描转换多边形的算法复杂而且它的应用非常多所以对其单独处理可以提高效率 原则左,下边的像素属于矩形而右上边的像素不属于矩形 左闭右开...
  • 多边形填充就是把多边形的顶点表示转换为点阵表示;4.3.2 多边形填充的扫描线算法;区域的连续性; (1)梯形的两底边分别在y= 和y= 两条扫描线上腰在多边 形P的边上或在显示屏幕的边界上 ;扫描线的连续性;边的连续性;...
  • 任意多边形填充,可以看看。自己用的话,还是动手的改的
  • 多边形填充实验

    2019-10-04 17:09:39
    实现多边形填充 步骤: 1.运行VC6.0 2.创建工程Fill , (工程类型选择:MFC Wizard (.exe) ) 3. 添加 "双击左键"和"单击右键"事件的消息响应 (1).选择菜单"View"->"class Wizard" (2)在弹...
    实验目标:
        1.窗口对用户"左按键"和"右按键"事件的响应
        2.实现多边形填充
    步骤:
    1.运行VC6.0
    2.创建工程Fill , (工程类型选择:MFC Wizard (.exe) )
    3. 添加 "双击左键"和"单击右键"事件的消息响应
        (1).选择菜单"View"->"class Wizard"
        (2)在弹出的窗口里
             classname: 选择CFillView
             Messages:  分别选择 WM_LBUTTONDBLCLK  , WM_RBUTTONDOWN      
             然后Add Function 
    4.修改代码:
         (1) 修改fillview.h文件 :
             在类的定义中,加入如下代码:
              public:
                    CPoint  spt[7];
                    void Floodfill(CPoint s_point, int f_color, int b_color) ; 
     
          
         (2)修改fillview.cpp文件 
             修改OnDraw,OnLButtonDblClk,OnRButtonDown的三个函数
             加入一个函数: Floodfill
         void CFillView::OnDraw(CDC* pDC)
           {
                  CFillDoc* pDoc = GetDocument();
                  ASSERT_VALID(pDoc);
                  CPen newpen(PS_SOLID,1,RGB(255,0,0));
                  CPen *old=pDC->SelectObject(&newpen);
                  pDC->TextOut(20,20,"双击鼠标左键, 出现需填充的多边形");
                  pDC->TextOut(20,50,"进行填充, 需用鼠标右键, 单击多边形内一点, 作为开始填充的种子点");
                pDC->SelectObject(old);
           }
          (2)void CFillView::OnLButtonDblClk(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     RedrawWindow();
     CDC* pDC=GetDC();
     CPen newpen(PS_SOLID,1,RGB(255,0,0));
     CPen *old=pDC->SelectObject(&newpen);
     //多边形各顶点的坐标
     spt[0]=CPoint(100,100);   
     spt[1]=CPoint(300,100);
     spt[2]=CPoint(250,250);
     spt[3]=CPoint(100,250);
     spt[4]=CPoint(150,200);
     spt[5]=CPoint(90,180);
     spt[6]=CPoint(150,150);
     spt[7]=CPoint(100,100);
     pDC->Polyline(spt,8);  //画多边形
     pDC->SelectObject(old);
     ReleaseDC(pDC);
     CView::OnLButtonDblClk(nFlags, point);
    }
     
    void CFillView::OnRButtonDown(UINT nFlags, CPoint point)
    {
     // TODO: Add your message handler code here and/or call default
     
     CView::OnRButtonDown(nFlags, point);
     int fill=RGB(0,255,0);
     int boundary=RGB(255,0,0);
        Floodfill(point, fill, boundary);
    }
     /*
          s_point 为种子点
          f_color是要填充的颜色, b_color是边界的颜色  
      */
    void CFillView::Floodfill(CPoint s_point, int f_color, int b_color)
    {
      
     CWindowDC     dc (this);
     int x,y,p0,pmin,pmax;
     
     //求多边形的最大最小值
     pmin=pmax=spt[0].y;
     for(int i=1;i<8;i++)
     {
     
       if(spt[i].y<pmin) pmin=spt[i].y;
        if(spt[i].y>pmax) pmax=spt[i].y;
     
     }
     x=s_point.x;
     y=s_point.y;
     for(;y<pmax;y++)
     {
     int current=dc.GetPixel(x,y);  
      while((current!=b_color)&&(current!=f_color))
       { 
        dc.SetPixel(x,y,f_color);
         x++; 
        current=dc.GetPixel(x,y);  
       }    
        x=s_point.x;
        x--;
        current=dc.GetPixel(x,y);
      while((current!=b_color)&&(current!=f_color))
       { 
        dc.SetPixel(x,y,f_color);
         x--; 
        current=dc.GetPixel(x,y);  
       }
      x=s_point.x;
     }
     x=s_point.x;
     y=s_point.y-1;
     for(;y>pmin+2;y--)
     {
     int current=dc.GetPixel(x,y);
    while((current!=b_color)&&(current!=f_color))
       { 
        dc.SetPixel(x,y,f_color);
         x++; 
        current=dc.GetPixel(x,y);
       }    
        x=s_point.x;
        x--;
        current=dc.GetPixel(x,y);
      while((current!=b_color)&&(current!=f_color))
       { 
        dc.SetPixel(x,y,f_color);
         x--; 
        current=dc.GetPixel(x,y);
       }
      x=s_point.x;
     }
    }
           
     

    转载于:https://www.cnblogs.com/qixin622/archive/2007/11/07/952181.html

    展开全文
  • 使用VS 2017实现多边形填充中的种子填充算法,此资源包括完整的项目文件,可以直接使用。此代码仅供学习交流使用。
  • 计算机图形学种子填充算法!多边形填充!能运行的源文件压缩包!
  • 计算机图形学的大实验,直线、圆、多边形画法,多边形填充算法,包括扫描线填充、四方向种子填充和种子栈填充,方法是,先画好多边形,点击多边形填充方法,选择好颜色后,点击多边形,就可自动填充。注意,种子填充...
  • 扫描多边形填充算法

    2016-02-26 20:21:35
    多边形填充,就是把多边形所占据的栅格象素赋予指定的颜色值。要完成这个任务,一个首要的问题就是求出多边形所占据的栅格象素,判断一个网格在多边形内还是多边形外,在多边形内的象素,则赋予指定的颜色值,多边形...

    http://www.cnblogs.com/carekee/articles/1769714.html

    扫描多边形填充算法

    多边形填充,就是把多边形所占据的栅格象素赋予指定的颜色值。要完成这个任务,一个首要的问题就是求出多边形所占据的栅格象素,判断一个网格在多边形内还是多边形外,在多边形内的象素,则赋予指定的颜色值,多边形外的象素,则不赋予指定的颜色值,具体该如何判断象素是否在多边形内呢?这里我们采用扫描线多边形填充算法

    扫描多边形填充算法的基本原理——在直角坐标系中,假设有一条从左至右的扫描线穿过多边形,从左至右开始计数,与多边形交点为奇数时,开始进入多边形,与多边形交点为偶数时,走出多边形。这样在这相邻配对的奇偶交点间的所有象素都在多边形内。如图,奇数交点ac,都是进入多边形,偶数交点bd都是走出多边形,相邻的奇偶交点配对,ab之间,cd之间的象素都在多边形内,可见一条扫描线上,与多边形交点个数需要为偶数。依据这样的思路,扫描线从上到下,从左到右依次扫过多边形即可求得多边形所占据的象素。(注意退化情况的处理,也就是扫描线刚好经过顶点或者多边形的边本身就是水平的情况)


    具体实现——首先,求多边形最上,最下的行号,以便于确定扫描线的行数,这个可以根据多边形的MBR求得;其次,确定一条扫描线上,与多边形的交点,保证交点个数为偶数,并对这些交点按列号从小到大排列;最后,扫描转换,扫描线从上到下,每条扫描线从左到右,对这些排序好的奇偶点配对连线。所采用的数据结构类似于“锯齿状的二维数组”,第一维代表行号,第二维代表一行中的交点。为了实现以上的步骤,需要对多边形边界进行栅格化,确定边界所经过的栅格,并把这些存储为“锯齿状的二维数组”(栅格化方法有:数值微分法,Bresenham算法,栅格中心线求交法)。退化情况的处理:

    一、边线端点的处理。比较此端点与它相邻的前后两端点所在扫描线的行号,设此端点的行号为h0,前一端点的行号为h1,后一端点的行号为h2。

    1)        h0>h1 and h0>h2,如图,点A、C、F,这些端点的栅格点不予以记录,即扫描线经过该点,计交点为0。

    2)        h0<h1 and h0<h2,如图,点B、E、G,这些端点的栅格点记录两次,即扫描线经过该点,计交点为2。

    3)        h0<h1 and h0>h2 or h0>h1 and h0<h2,如图,点D,H,这些端点的栅格点记录一次,即扫描线经过该点,计交点为1。


    二、水平线的处理。多边形边线段,扫描出来为一横线,即一条线段从头到尾都占据一行栅格。理论上,这种情况与扫描线有无数个交点,为了保持一行中交点个数为偶数,判断当前横线段与前后相邻两条线段的位置关系,同时先栅格化此横线,作以下规定。

    1)        前后相邻两线段位于此横线段的异侧,如图,横线段AB,前后两线段AIBC位于横线段AB的异侧,则与此横线段交点计为1,记录A点或者B点,均可。

    2)        前后相邻两线段位于此横线段的同侧,如图,横线段GF,前后两线段GHFE位于横线段GF的同侧,则与此横线段交点计为0,不记录任何交点。


    这种判断的思想是这样的:基于动态的思想,横线AB,假设A和B两点相互靠近,最终成为一点,假设为A‘,根据端点处理的方法,A’介于前后两点I、C之间,应计交点一个,而对于横线GF,一样的道理,GF相互靠近最终成为一点,假设为F‘,根据端点处理的方法,F’大于前后两点E、H,应计交点0。这种判断可以有效处理横线,但又带来一个新的问题,如果相邻前或者后两线段也是同此横线一样,也是在这一行水平,这样就要递推到更前或者更后的线段,直到找出以上判断的条件。


    如图,判断线段AB,需要找到前一条线段AJ,后一条线段BC,由于BC与AB都是水平的,需要找再下一条CD,得到AJ、CD位于水平线的异侧,则计交点为1。判断线段GH,前后两线段GF、HI都是水平的,需要分别寻找更前,、更后的线段FE、IJ,一直递归下去,直到确定判断条件。如果觉得这种情况比较麻烦,在程序端点循环的时候,找到第一段不是横线的起点开始循环,这样,只要判断,横线后面条线段的情况,直到确定判断条件即可。

    展开全文
  • 基于扫描线的任意多边形填充算法
  • 一 吴厶 成绩 实验项目名称 多边形填充算法 实 验 使学生掌握光栅显示系统中多边形的扫描转换和区域填充算法掌握 4连通区域的扩展性 目 实 验 要 求实现多边形的扫描转换算法和区域填充算法 实 验 要 求 实现多边形...
  • 多边形填充算法,c语言版,实现了多边形填充扫描线算法
  • 关于扫描线填充和种子填充、以及多边形种子填充
  • 使用MFC进行画直线以及多边形填充算法
  • 多边形填充算法之扫描线填充算法  多边形填充可以是凸多边形、凹多边形、或者是可以是带孔的多边形。扫描线填充算法是一种常用的填充算法。 1. 多边形填充过程一般可以分为四个步骤  (1)求交:计算扫描线与...

    多边形填充算法之扫描线填充算法

      多边形填充可以是凸多边形、凹多边形、或者是可以是带孔的多边形。扫描线填充算法是一种常用的填充算法。

    1. 多边形填充过程一般可以分为四个步骤

      (1)求交:计算扫描线与多边形各边的交点;

      (2)排序:把所有交点按照递增的顺序进行排序;

      (3)交点配对:1与2, 3与4等配对处理,每对代表扫描线与多边形的一个相交的区间;

      (4)区间填充:把这些相交的区间内的像素设置成多边形颜色,填充区间之外的像素设置背景色。

    2. 需要解决的问题

      (1)扫描线与多边形相交时,交点的取舍问题;

      (2)多边形边界的像素取舍问题。

    3. 问题解决

      

       (1) 扫描线交于多变型的顶点时,根据顶点的对应的两条边的另一个顶点的位置来判断取舍。

      ① 如果另外两个顶点都高于扫描线,则取这个顶点算取2次,即此顶点可以填充,已经作为填充区间;

      ② 如果另外两个顶点都低于扫描线,则这个交点算取0个,即此顶点不进行填充;

      ③ 如果另外两个顶点一个在扫描线之上,另一个在扫描线之下,则这个交点算取1次,需要与另一个交点进行配对组成填充区间。

      (2) 多边形填充区间的边界取舍问题:遵循“左下闭,右上开”的原则,来避免填充区域扩大的问题。

      即落在左下边界的像素进行填充,而落在右上的像素不进行填充,简单解释就是,如果扫描线交点是1和9,则实际填充的区间是[1,9),即不包括x坐标是9的那个点。

      具体实现时,对扫描线取左闭右开。

      由以上两个策略,综合效果是实现“左下闭,右上开”。

    4. 填充算法的4个中的问题

      了解几个“连贯性”的概念:

      “边的连贯性”:多边形与扫描线相交的边,在一定的范围内,相交的边保持一定的不变性,也可以理解为,当一条便于当前扫描新相交时,其也可能与下一条扫描线相交;

      “扫描线的连贯性”:扫描线与多边形相交的交点,由于其连贯性,新的交点序列与之前的交点序列(交点的排序)基本保持一致,最多有几个个别的交点的位置需要调整,整体上都是按照交点X值得递增的顺序排列,在程序实现上,可以借助这个特定实现排序效率的提高;

      “扫描区间的连贯性”:对确定好的扫描线的填充区间,即区间内的开始点X值到区间结束X值,同一区间上的像素填充颜色相同。可以直接绘制一条区间内的填充色的线段,提高渲染效率。

     (1)求扫描线与多边形的求交运算问题,如果扫描线分别对所有的边进行求交判定,这样处理效率非常低,其中大量的判定计算都是徒劳的;

      为了提高求交运算的效率,设定“AET活性边界表”。

      “AET活性边表”:把于扫描线相交的边称为活性边,并把他们按照与扫描线交点的X坐标递增的顺序放在一个链表中,这样的链表称为“AET(Active Edge Table)活性边表”。

      活性编标的

     

     (2)

    5. 算法步骤

     1 算法过程:
     2 void polyfill (polygon, color)
     3 int color;多边形 polygon;
     4 {
     5 for (各条扫描线i )
     6 {    初始化新边表头指针NET [i];
     7     把y min = i 的边放进边表NET [i];
     8      }
     9    y = 最低扫描线号;
    10      初始化活性边表AET为空;
    11   for (各条扫描线i )
    12     {    把新边表NET[i]中的边结点用插入排序法插入AET表,使之按x坐标递增顺序排列;
    13          遍历AET表,把配对交点区间(左闭右开)上的象素(x, y),
    14       用drawpixel (x, y, color) 改写象素颜色值;
    15          遍历AET表,把ymax= i 的结点从AET表中删除,并把ymax > i结点的x值递增Dx;
    16          若允许多边形的边自相交,则用冒泡排序法对AET表重新排序;
    17     }
    18 } /* polyfill */

       注意问题

      (1)初始化新边表数组时,各个数据项中的节点按照X递增的顺序排列;

      ()

      ()把判定如有新的表插入时,则将新的列表中的节点,通过“插入排序”进行插入操作;

      ()

     

     

     

      由以上

    转载于:https://www.cnblogs.com/icmzn/p/5053317.html

    展开全文
  • 本文主要介绍几种区域填充算法,重点解释多边形的扫描线填充算法,最后实现了多边形填充算法,包括在附录文件中。在参考【5】中,作者详细介绍了一系列区域填充算法,可以查看相应网页。代码的下载地址为:...

    本文主要介绍几种区域填充算法,重点解释多边形的扫描线填充算法,最后实现了多边形填充算法,包括在附录文件中。在参考【5】中,作者详细介绍了一系列区域填充算法,可以查看相应网页。代码的下载地址为:https://github.com/twinklingstar20/twinklingstar_cn_region_polygon_fill_scanline/

    1. 1.区域的定义和填充

    1.1像素定义的区域(Pixel-Defined Region)

    1.1.1        边界定义区域(boundary-defined)

    定义某些像素是边界,边界包围着一块区域。填充所有在边界内的相连通的像素,主要分下面几个步骤:

    从区域内部一个像素点开始

    判断这个像素是否是一个边界像素点或者已经被填充了

    如果都不是,就把它填充,然后开始设置邻居像素点。

    用图片演示这个过程,如下面的幻灯片所示,代码片段如下所示:

    void boundaryFill4 (int x, int y, int fill, int boundary)

    {

    int current;

    current = getPixel (x,y);

    if (current != boundary && current !=fill)

    {

    setColor(fill);

    setPixel(x,y);

    boundaryFill4 (x+1, y, fill, boundary);

    boundaryFill4 (x−1, y, fill, boundary);

    boundaryFill4(x, y+1, fill, boundary);

    bonddaryFill4(x, y−1, fill, boundary);

    }

    }

    1.1.2          内定义区域(interior-defined)

    内定义区域的定义是:给定一个像素S,颜色是C,区域R指与S连通的且颜色都是C的像素集合(Region R is the set of all pixels having color C that are “connected” to a given pixel S)。

    如果两个像素连通,则它们之间有一条“相邻(adjacent)”像素组成的连续路径,所以连通的概念就依赖“相邻”的定义。在图形学中,相邻通常有两种定义:

    (1)       四相邻(4-Adjacent):两个像素是四相邻的,则它们在彼此水平或者垂直相邻的位置上,如图1所示:

    图1. 四相邻

    (2)       八相邻(8-Adjacent):两个像素是八相邻的,则它们在彼此水平、垂直或者是斜方向上相邻的位置,如图2所示:

    图2. 八相邻

    如果两个像素是四连通(4-connected),指它们之间有一条四相邻像素组成的连续路径;如果两个像素是八连通(8-connected),指它们之间有一条四相邻像素组成的连续路径。举个例子,如下图3所示,是由黑色、灰色和白色组成的像素图,给定一个像素点S,则由它定义的四连通区域共有20像素,由它定义的八连通区域共有28个像素。

    图3 像素区域

    这里介绍两种简单的填充算法:

    (1)       一种称为洪水填充法。规定采用4连通的区域,下面用幻灯片演示了这个过程,下面的代码片段实现了该算法。由于没有使用到区域间的相关性,很多像素点可能会重复被填充。

    从内部一个像素点开始,并用新的颜色替换它

    填充四连通或者八连通区域,直到所有的内部点被替换了

    void floodFill4 (int x, int y, int fill, int oldColor)

    {

    if (getPixel(x,y) == oldColor)

    {

    setColor(fill);

    setPixel(x,y);

    floodFill4 (x+1, y, fill, oldColor);

    floodFill4 (x−1, y, fill, oldColor);

    floodFill4(x, y+1, fill, oldColor);

    floodFill4(x, y−1, fill, oldColor);

    }

    }

    缺点是:1)大量的嵌套调用;2)很多像素点可能会被测试多次;3)难以清楚的掌控由于嵌套调用所占的内存大小;4)如果算法多次测试一个像素,会导致占用的内存扩大。

    (2)利用像素间的相关性,可以提高算法的性能,并避免堆栈的溢出。每次填充在同一条扫描线上相邻的一排像素,同时把与它相邻的未填充的种子像素放在堆栈中,下面的幻灯片演示了这个过程。伪码如下所示:

    Push address of seed pixel on the stack;

    while( stack not empty)

    {

    Pop the stack to provide the next seed;

    Fill the run defined by the seed;

    In the row above find interior runs reachable from this run;

    Push the addresses of the rightmost pixels of each such run;

    Do the same for the row below the current run;

    }

    1.2符号定义的区域(Symbolically Defined Region)

    这里简单介绍下符号定义的区域的分类,详细参见参考【4】,主要包括两类:

    (1)用一系列的矩形方块表示的区域;

    (2)通过一条表示一个区域边界的路径来界定一个区域:

    1)用一个数学公式来定义边界,例如采用(x-122)^2+(y-36)^2=25来定义一个圆的区域

    2)通过一系列的多边形顶点,像(x1,y1),(x2,y2),(x3,y3)…(xn,yn)来定义一个多边形区域

    3)通过一系列相邻的像素来定义。

    4)链码(chain code),这是一个很经典的方法,在参考【3】和【4】中都有简单的介绍,这里不详细介绍这块知识

    5)其它

    2.多边形填充算法

    2.1算法思想

    参考【5】,扫描线填充算法的基本思想是:每条水平扫描线与多边形的边产生一系列交点,交点之间形成一条一条的线段,该线段上的像素就是需要被填充的像素。将这些交点按照x坐标排序,将排序后的交点两两成对,作为线段的两个端点。水平扫描线从上到下(或从下到上)扫描由多条首尾相连的线段,使用要求的颜色填充该水平线段上的像素。多边形扫描完成后,颜色填充也就完成了。扫描线填充算法可以归纳为以下4个步骤:

    (1)       求交,计算扫描线与多边形的交点;

    (2)       交点排序,对第(1)步得到的交点按照x值从小到大进行排序;

    (3)       颜色填充,对排序后的交点两两组成一个水平线段,以画线段的方式进行颜色填充;

    (4)       是否完成多边形扫描?如果是就结束算法,如果不是就改变扫描线,然后转第1步继续处理;

    整个算法的关键是第1步,需要用尽量少的计算量求出交点,还要考虑交点是线段端点的特殊情况,最后,交点的计算最好是整数,便于光栅设备输出显示。对于每一条扫描线,如果每次都按照正常的线段与直线相交算法进行计算,则计算量大,而且效率低下,如图(4)所示:

    图4. 扫描线算法

    2.2存在的问题

    利用上述算法还存在几个问题,接下来分别讨论:

    (1)       如果多个多边形相邻的话,它们可能会共享一条边,那么共享边可能会被绘制两次,图5和图6演示了该错误:

    图5. 相邻的两个三角形共享边

    图6. 左图是背景颜色与前景颜色混合的情况,右图是不绘制共享边的情况

    对这个问题有一种很好的解决方案是:

    原则1:每个多边形只拥有它左边的像素,即采用左闭右开的原则,如果边是水平的话,则只拥有底边。

    图7. 共享边的解决方案

    (2)       如图7所示,若采用Bresenham直线绘制算法,(参见文章,《布雷森汉姆直线算法》可能会出现一些像素超出边所在的范围:

    原则2:在计算完扫描线与边的交点后,会形成一条条的首尾相连的线段,用xLeft表示左端点,xRight表示右端点,xLeft和xRight是实数,取大于等于xLeft的最小整数xNewLeft,取小于等于xRight的最大整数xNewRight,则绘制像素范围是[xNewLeft,xNewRight),如果xNewRight

    (3)       水平扫描线与端点发生相交的情况。如图8所示,穿过顶点H的扫描线,发生了两次相交(一次是与边GH,一次是与边HI),所以2.1描述的算法思想的第1步结束后,H点会存储两次,排完序后H两边的奇偶性会相同,因此会错误的将H右边的像素进行填充。(本图是从参考【4】中获取的,个人觉得该图解释这个问题,有点牵强。如果整个图左右翻转的话,解释这个问题就特别清楚了,算法思想的第1步结束后,该扫描线上共有三个交点:(H,H,右交点),这样问题就明显了)。这里采用两条原则,可以很简单的解决这个问题:

    图8. 填充多边形

    原则3:忽略任何一条与水平边的相交计算;

    原则4:如果交点是边的上端点,则把该端点忽略。

    举个遵守该该原则的例子,如图9所示,得到每条边端点相交的数量:

    图9. 一个多边形的端点相交的数量

    2.3数据结构设计

    2.3.1活动边链表(Active-Edge List,AEL)

    在计算相邻两条扫描线与一条边的相交时,可以利用它们之间的相关性。假设,一条边与的斜率是k,与扫描线y相交于x,则该边与扫描线y+1相交于x+1/k点的位置,利用这个特性可以减少运算量。为了方便进行该运算,有人提出了一种数据结构,称为活动边链表,链表的每个节点存储三个数据:(1)与当前水平扫描线的交点xint;(2)斜率m的倒数,1/m;(3)边的上端点的yhigh。举个例子来说该结构的存储方式,如图10所示,虚线代表了水平扫描线,在该水平扫描线上与多边形共有4个交点,则在AEL中会存储4个节点,4个结点按照xint从小到大排序。

    图10. 活动边链表

    2.3.2边表(Edge Table,ET)

    边表存储的是边的信息,边表中每个节点的数据结构与AEL中每个节点的相同,同样存储了三个信息:(1)边下端点X坐标xbottom;(2)边斜率的倒数;(3)边上端点Y坐标yhigh。当AEL表进行更新时,边表这种数据结构提供了快速索引的功能。如图10中多边形的边信息,用边表表示,如图11所示,这里就记录了其中四条边的信息。首先用一个边节点的数组,一条边下端点的Y坐标值,表示该数组的索引。图10中,Y=20扫描线上,共有两条边(原则3,忽略水平边),所以把两条边的信息记录节点,该节点存储在数组索引号20的表项后面,注意:在我的实现中,要求这个链表中的节点也是按照xbottom从小到大的顺序排列的;例如扫描线39所示,不存在边的下端点在该扫描线上,则索引号39的表项后面为空。

    图11. 边表

    2.4算法实现

    如下面的代码片段所示,主要有如下几个步骤:

    (1)       分配AEL的表头g_ptrAELHead和边表g_ptrEdgeTable[EDGE_TABLE_SIZE]的表头内存空间,由于现在显示器在垂直方向的分辨率一般不超过1024,所以这里不进行优化。

    (2)       初始化边表

    (3)       在当前扫描线上,在ET中是否存在表项,如果存在,则插入到AEL表中。

    (4)       填充该扫描线

    (5)       更新AEL。AEL中是否有边的y坐标值大于或者等于下一条扫描线(原则1:上边不进行绘制),由于AEL结点中保存有yhigh,这一步很容易判断,将相应的节点删除。

    (6)       判断算法是否结束,否则的话重复(3)-(5)几个步骤。

    typedef struct _Edge

    {

    doubledbX;

    doubledbDelta;

    intinMaxY;

    _Edge*ptrNext;

    }Edge;

    Edge*g_ptrEdgeTable[EDGE_TABLE_SIZE];

    Edge*g_ptrAELHead;

    void scanLineFill(Vector* ptrPolygon, int inNumPoly,DWORD inColor)

    {

    allocEdges();

    initEdgeTable(ptrPolygon,inNumPoly);

    for(int y=g_inMinY ; y

    {

    insertAEL(g_ptrAELHead,g_ptrEdgeTable[y]);

    fillAELScanLine(g_ptrAELHead,y,inColor);

    updateAEL(g_ptrAELHead,y+1);

    }

    deallocEdges();

    }

    2.5算法结果演示

    如图12所示,实现该算法,并用glut库实现了个简单的Demo,按’U’,’L’可以放大或者缩小图像,即放大缩小每个“像素”占据的像素大小。

    图12. 算法演示

    3.参考

    【3】冈萨雷斯《数字图像处理》

    【4】F.S Hill, JR. 《Computer Graphics Using OpenGL, Second Edition》

    展开全文
  • 多边形填充 C代码

    2010-10-20 19:01:01
    对凹多边形填充的C语言代码,并且支持按多边形变数的选择。
  • 计算机图形学课件,第四章 多边形填充.ppt
  • OpenGL-扫描多边形填充算法

    千次阅读 2016-07-18 16:59:29
    扫描多边形填充算法 多边形填充,就是把多边形所占据的栅格象素赋予指定的颜色值。要完成这个任务,一个首要的问题就是求出多边形所占据的栅格象素,判断一个网格在多边形内还是多边形外,在多边形内的象素,则赋予...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,410
精华内容 964
关键字:

多边形填充