扫描线算法

合集下载

基于扫描线的线段求交算法

基于扫描线的线段求交算法

基于扫描线的线段求交算法扫描线算法是一种计算线段交点的常用方法。

它的基本思想是,将二维空间中的线段拆分成多个水平线段,然后通过遍历扫描线的方式,将每条扫描线与线段进行求交。

具体实现上,我们可以按照以下步骤进行:1.线段拆分:将给定的线段按照两端点的纵坐标从小到大进行排序,将线段分割成多个水平线段。

每个水平线段由一个起点和一个终点组成,起点的y值小于终点的y值。

2.扫描线初始化:将扫描线从最小的y值开始,以步长为1沿着y轴向上移动。

3.当前线段集合初始化:将与当前扫描线y值相交的水平线段添加到当前线段集合中。

4.求交点:遍历当前线段集合,将相邻的水平线段进行求交,得到所有线段交点。

5.更新当前线段集合:将终点y值小于当前扫描线y值的水平线段从当前线段集合中移除。

6.更新扫描线:将扫描线向上移动一个步长。

7.重复步骤3-6,直到扫描线超过最大的y值,并且当前线段集合为空。

在该算法中,关键的步骤是求交点的过程。

可以使用一维直线相交的算法,如线性插值,来计算线段的交点。

扫描线算法的时间复杂度主要取决于线段的数量和扫描线的数量。

对于n个线段和m个扫描线,时间复杂度可以达到O(nlogn + m)。

这种算法广泛应用于计算机图形学中的线段裁剪、多边形填充等领域。

它的优点是简单易懂,实现相对容易,并且可以高效地处理大量的线段求交问题。

然而,扫描线算法在处理复杂的线段求交问题时可能会遇到一些挑战。

例如,当线段存在重叠或相交的情况时,需要特殊处理来确保交点的正确性。

此外,当线段的数量较多时,算法的时间复杂度可能会较高,导致计算效率下降。

总之,扫描线算法是一种经典的线段求交算法,通过拆分线段和遍历扫描线的方式,可以高效地计算出线段的交点。

在实际应用中,我们可以结合具体问题的特点,采用一些优化策略来提高算法的效率和稳定性。

扫描线填充算法讲解

扫描线填充算法讲解

扫描线算法(Scan-Line F illing)扫描线算法适合对矢量图形进行区域填充,只需要直到多边形区域的几何位置,不需要指定种子点,适合计算机自动进行图形处理的场合使用,比如电脑游戏和三维CAD软件的渲染等等。

对矢量多边形区域填充,算法核心还是求交。

《计算几何与图形学有关的几种常用算法》一文给出了判断点与多边形关系的算法――扫描交点的奇偶数判断算法,利用此算法可以判断一个点是否在多边形内,也就是是否需要填充,但是实际工程中使用的填充算法都是只使用求交的思想,并不直接使用这种求交算法。

究其原因,除了算法效率问题之外,还存在一个光栅图形设备和矢量之间的转换问题。

比如某个点位于非常靠近边界的临界位置,用矢量算法判断这个点应该是在多边形内,但是光栅化后,这个点在光栅图形设备上看就有可能是在多边形外边(矢量点没有大小概念,光栅图形设备的点有大小概念),因此,适用于矢量图形的填充算法必须适应光栅图形设备。

2.1扫描线算法的基本思想扫描线填充算法的基本思想是:用水平扫描线从上到下(或从下到上)扫描由多条首尾相连的线段构成的多边形,每根扫描线与多边形的某些边产生一系列交点。

将这些交点按照x坐标排序,将排序后的点两两成对,作为线段的两个端点,以所填的颜色画水平直线。

多边形被扫描完毕后,颜色填充也就完成了。

扫描线填充算法也可以归纳为以下4个步骤:(1)求交,计算扫描线与多边形的交点(2)交点排序,对第2步得到的交点按照x值从小到大进行排序;(3)颜色填充,对排序后的交点两两组成一个水平线段,以画线段的方式进行颜色填充;(4)是否完成多边形扫描?如果是就结束算法,如果不是就改变扫描线,然后转第1步继续处理;整个算法的关键是第1步,需要用尽量少的计算量求出交点,还要考虑交点是线段端点的特殊情况,最后,交点的步进计算最好是整数,便于光栅设备输出显示。

对于每一条扫描线,如果每次都按照正常的线段求交算法进行计算,则计算量大,而且效率底下,如图(6)所示:图(6)多边形与扫描线示意图观察多边形与扫描线的交点情况,可以得到以下两个特点:(1)每次只有相关的几条边可能与扫描线有交点,不必对所有的边进行求交计算;(2)相邻的扫描线与同一直线段的交点存在步进关系,这个关系与直线段所在直线的斜率有关;第一个特点是显而易见的,为了减少计算量,扫描线算法需要维护一张由“活动边”组成的表,称为“活动边表(AET)”。

X-扫描线算法

X-扫描线算法

X-扫描线算法多边形的扫描转换(X-扫描线算法)⼀、两种表⽰⽅法把多边形的顶点表⽰转换为点阵表⽰称为多边形的扫描转换。

⼆、X-扫描线算法 图1 图21.步骤a. 求交b. 排序:把所有交点按递增顺序排序为何要进⾏排序?答:按交点x值递增排序,确保交点两两配对时填充区间的正确性。

c. 交点配对:确定填充区间d. 区间填⾊2.交点取舍(当扫描线与多边形顶点相交时,交点如何取舍?)两边只取1,同边0或2。

三、X-扫描线算法的改进1. 三⽅⾯的改进a. 处理⼀条扫描线,仅对与它相交的多边形的边(有效边)进⾏求交运算。

(也就是避免把所有的边都进⾏求交,因为⼤部分的边求交结果为空。

所以设置⼀个表来记录有效边。

即下⾯提到的AET)b. 考虑边的连贯性:当前扫描线与各边的交点顺序与下⼀条扫描线与各边的交点顺序很可能相同或⾮常相似。

c. 多边形的连贯性:当某条边与当前扫描线相交时,它很可能也与下⼀条扫描线相交。

2.数据结构通过引⼊新的数据结构来避免求交运算(1)活性边表a. 活性边表(AET):把和当前扫描线相交的边称为活性边,并把它们按交点x坐标递增的顺序存于⼀个链表中。

b. 结点内容Δx=1/k,y max 是为了知道何时达到边界c. 举例(2)新边表(NET)建⽴AET需要知道与哪些边相交,所以定义NET来存储边的信息,从⽽⽅便AET的建⽴。

a. 构造⼀个纵向链表,长度为多边形占有的最⼤扫描线数。

每个节点(称为吊桶)对应多边形覆盖的⼀条扫描线。

b. 结点内容y max:该边的y最⼤值x min:该边较低点的x坐标c. NET挂在与该边较低端y值相同的扫描线吊桶中此时NET也就记录了6条有效边(3)NET与AET的使⽤流程⾸先我们得明⽩,AET的⽬的是为了使⽤增量⽅法避免求交运算,⽽NET是⽤在构造AET的。

a. 所以第⼀步为构造NET。

⽅法:遍历所有扫描线,把y min = i 的边放进NET[ i ]中,从⽽构造出整个NET。

用扫描线算法实现多边形填充

用扫描线算法实现多边形填充

用扫描线算法实现多边形填充扫描线算法是一种用于多边形填充的有效方法。

它的思想是遍历扫描线,并在每条扫描线与多边形边界相交时填充相应的像素。

首先,我们需要了解多边形表示的方法。

多边形可以用一系列有序的边来表示,每条边由起点和终点坐标组成。

例如,一个三角形可以表示为三条线段的集合。

接下来,我们将介绍如何使用扫描线算法来实现多边形填充:1.首先,找到多边形的最大和最小y坐标,即多边形的上边界和下边界。

2.从上边界开始,逐条扫描线遍历到下边界。

3.在每条扫描线上,确定与多边形边界相交的线段。

4.根据与多边形边界相交的线段的起点和终点,找到对应的x坐标范围。

5.根据x坐标的范围,填充相应的像素。

下面是一个使用扫描线算法填充多边形的伪代码示例:```ScanLineFill(polygon):ymin = polygon.minYymax = polygon.maxYfor y from ymin to ymax:intersections = FindIntersections(polygon, y)sort(intersections)for i from 0 to length(intersections) - 1 by 2:xstart = intersections[i]xend = intersections[i+1]FillPixels(xstart, xend, y)```此伪代码的`FindIntersections`函数是用来找到多边形边界与当前扫描线相交的点,而`FillPixels`函数则用来填充相应的像素。

在实际实现时,可以使用一些数据结构来存储多边形的边界信息和扫描线与边界相交的点。

例如,可以使用边表来存储多边形的边界,使用活性边表来存储与当前扫描线相交的边界,使用扫描线来表示当前的扫描线位置。

算法的时间复杂度主要取决于扫描线与边界相交点的计算,可以通过使用边表和一些优化技巧来降低时间复杂度。

实验报告(扫描线算法)

实验报告(扫描线算法)

实验报告(扫描线算法)一、实验目的学习扫描线算法,掌握种子区域填充的程序设计方法。

二、实验原理A.多边形扫描转换根据区域的连贯性、扫描线的连贯性、边的连贯性以及奇点的处理方法,做出基于扫描线算法数据结构(ET&AEL )的扫描线算法程序。

其算法的实现步骤如下:1) (扫描线初始化)取扫描线纵坐标y 的初始值为ET 中非空元素的最小序号。

(对给定的多边形,y=constant );2) (AEL 初始化)将边的活化链表AEL 置为空表;3) 按从下到上的顺序对纵坐标值为y 的扫描线执行以下操作,指导边的分类表ET 和边的活化链表AEL 为空表为止;①若ET 中第y 类元素非空,则将属于该类的所有边从ET 中取出并插入到AEL 中。

AEL 中的各边按照x 的值(当x 值相等时,按x ∆值)递增的顺序排序。

②若相对当前扫描线,AEL 非空,则将AEL 中的边两两配对。

即第1、2边为一对,第3、4边为一对,以此类推。

每一对边与当前扫描线的交点所构成的区段位于多边形内。

依次对这些区段上的像素点按多边形颜色着色。

③将AEL 中满足条件y y =max 的边删去。

④将AEL 中剩余的每一条边的x 域累加x ∆,即x x x ∆+=。

⑤将当前扫描线的纵坐标值y 累加1,即y y y ∆+=。

B.多边形的填充(边界标志算法)先用一种特殊颜色在帧缓冲器中将多边形的边界(水平边界除外)勾画出来,然后再用类似扫描线算法的方法对于多边形内的各区段着上所需颜色。

三、实验程序//A.多边形扫描转换#include<stdio.h>#include<graphics.h>#include<easyx.h>#include<conio.h>#define YMAX 480 /*宏定义*/typedef struct tEdge //定义结构体{int yUpper,yLower;float xIntersect,dxPerScan;struct tEdge *next;struct tEdge *active;}Edge;void insertEdge (Edge *list,Edge *edge) //将结点插入边表{Edge *p,*q=list;p=q->next;while (p!=NULL){if(edge->xIntersect<p->xIntersect)p=NULL;else{q=p;p=p->next;}}edge->next=q->next;q->next=edge;}int yNext (int k,int count,int *y) //求奇异点{int j;if((k+1)>(count-1))j=0;elsej=k+1;while(y[k]==y[j])if((j+1)>(count-1))j=0;elsej++;return(y[j]);}void makeEdgeRecord(int xLower,int yLower,int xUpper,int yUpper,int yComp,Edge *edge,Edge *edges[])//生成边表结点,并插入到边表中{edge->dxPerScan=(float)(xUpper-xLower)/(yUpper-yLower);edge->yUpper=yUpper;if(yLower>yComp){edge->yLower=yLower+1;edge->xIntersect=xLower+edge->dxPerScan;}elseedge->xIntersect=(float)xLower;insertEdge(edges[yLower],edge);}void buildEdgeList(int count,int *x,int *y,Edge *edges[]) //创建边表的主体函数{Edge *edge;int x1,y1,x2,y2;int i,yPrev=y[count-2];x1=x[count-1];y1=y[count-1];for(i=0;i<count;i++){x2=x[i];y2=y[i];if(y1!=y2){edge=(Edge *)malloc(sizeof(Edge));if(y1<y2)makeEdgeRecord(x2,y2,x1,y1,yNext(i,count,y),edge,edges);elsemakeEdgeRecord(x1,y1,x2,y2,yPrev,edge,edges);}yPrev=y1;x1=x2;y1=y2;}}void buildActiveList(int scan,Edge *active,Edge *edges[]) //建立活动边表的主体函数{Edge *p,*q;p=edges[scan]->next;while(p){q=p->next;insertEdge(active,p);p=q;}}void fillScan(int scan,Edge *active) //填充当前扫描线{Edge *p1,*p2;int i,PolygonColor=25;p1=active->next;while(p1);{p2=p1->next;for(i=(int)p1->xIntersect;i<p2->xIntersect;i++)putpixel(i,scan,PolygonColor);p1=p2->next;}}void deleteAfter(Edge *q) //删除已经处理过的边{Edge *p=q->next;q->next=p->next;free(p);}void updateActiveList(int scan,Edge *active) //更新活化链表{Edge *q=active,*p=active->next;while (p)if(scan>=p->yUpper){p=p->next;deleteAfter(q);}else{p->xIntersect=p->xIntersect+p->dxPerScan;q=p;p=p->next;}}void resortActiveList(Edge *active) //活化链表排序{Edge *q, *p=active->next;while(p){q=p->next;insertEdge(active,p);p=q;}}void scanFillPolygon(int count,int *x,int *y) //多边形扫描转换{Edge *edges[YMAX],*active;int i,scan;//扫描线的边界for(i=0;i<YMAX;i++){edges[i]=(Edge *)malloc(sizeof(Edge));//申请空间edges[i]->next=NULL;}buildEdgeList( count, x, y, edges);active=(Edge *)malloc(sizeof(Edge));active->next=NULL;//初始化边表for(scan=0;scan<YMAX;scan++){buildActiveList(scan,active,edges);if (active->next){fillScan(scan,active);updateActiveList(scan,active);resortActiveList(active);}}free(active);}void main(){int gdriver = DETECT,gmode;initgraph(700,600); //初始化窗口大小int x[]={240,390,540,232};int y[]={150,230,430,370};int count=4;line(240,150,390,230);line(390,230,540,430);line(540,430,232,370);line(232,370,240,150);scanFillPolygon(count,x,y);getch();//暂停程序closegraph();//退出图形库}//B.多边形的填充(失败)四、测试结果A.多边形扫描转换B.多边形的填充(失败)。

扫描线填充算法讲解

扫描线填充算法讲解

扫描线算法(Scan-Line F illing)扫描线算法适合对矢量图形进行区域填充,只需要直到多边形区域的几何位置,不需要指定种子点,适合计算机自动进行图形处理的场合使用,比如电脑游戏和三维CAD软件的渲染等等。

对矢量多边形区域填充,算法核心还是求交。

《计算几何与图形学有关的几种常用算法》一文给出了判断点与多边形关系的算法――扫描交点的奇偶数判断算法,利用此算法可以判断一个点是否在多边形内,也就是是否需要填充,但是实际工程中使用的填充算法都是只使用求交的思想,并不直接使用这种求交算法。

究其原因,除了算法效率问题之外,还存在一个光栅图形设备和矢量之间的转换问题。

比如某个点位于非常靠近边界的临界位置,用矢量算法判断这个点应该是在多边形内,但是光栅化后,这个点在光栅图形设备上看就有可能是在多边形外边(矢量点没有大小概念,光栅图形设备的点有大小概念),因此,适用于矢量图形的填充算法必须适应光栅图形设备。

扫描线算法的基本思想扫描线填充算法的基本思想是:用水平扫描线从上到下(或从下到上)扫描由多条首尾相连的线段构成的多边形,每根扫描线与多边形的某些边产生一系列交点。

将这些交点按照x坐标排序,将排序后的点两两成对,作为线段的两个端点,以所填的颜色画水平直线。

多边形被扫描完毕后,颜色填充也就完成了。

扫描线填充算法也可以归纳为以下4个步骤:(1)求交,计算扫描线与多边形的交点(2)交点排序,对第2步得到的交点按照x值从小到大进行排序;(3)颜色填充,对排序后的交点两两组成一个水平线段,以画线段的方式进行颜色填充;(4)是否完成多边形扫描?如果是就结束算法,如果不是就改变扫描线,然后转第1步继续处理;整个算法的关键是第1步,需要用尽量少的计算量求出交点,还要考虑交点是线段端点的特殊情况,最后,交点的步进计算最好是整数,便于光栅设备输出显示。

对于每一条扫描线,如果每次都按照正常的线段求交算法进行计算,则计算量大,而且效率底下,如图(6)所示:图(6)多边形与扫描线示意图观察多边形与扫描线的交点情况,可以得到以下两个特点:(1)每次只有相关的几条边可能与扫描线有交点,不必对所有的边进行求交计算;(2)相邻的扫描线与同一直线段的交点存在步进关系,这个关系与直线段所在直线的斜率有关;第一个特点是显而易见的,为了减少计算量,扫描线算法需要维护一张由“活动边”组成的表,称为“活动边表(AET)”。

扫描线算法——精选推荐

扫描线算法——精选推荐

扫描线算法先从⼀道模板题⼊⼿吧..这道题需要我们求n个矩形的⾯积并。

~~ 数据还很变态 ~~给出这n的矩形的左下⾓和右上⾓坐标,~~ ≤10^9 只能⽤离散化,离散化之后最多到n也就是10^5,能够维持。

怎么做?for循环?T(LE)M(LE)⼤套餐等着你离散化之后循环都要超时还存不下 ~~先把所有的⾯积相加再减去重复?~~ 现实点,你做不到 ~~扫描线算法基础就是应对这种问题的。

它的思想是分割图形⽐如说,有n个矩形组成这张图。

我们设想,有⼀条⽆限长度的竖线⾃左往右扫过这⼀⽚图形。

只保留这些矩形被竖线扫到的左右两条线段,组成包含2*n条线段的⼀张图。

对于每个矩形,把左边那条线段记为+1,右边的记为-1.像这样:对于两两相邻的部分,我们可以分别计算⾯积,这样就得到了整个并集图形的⾯积。

怎么记录这⼀条条线段?结构体。

要存储的东西有:这条竖线段的横坐标,上下端点的竖坐标,以及1/-1(记录是左还是右)按照题⽬表述记为:{x,y1,y1,1/-1}显然,我们只要把这些线的横坐标拿来排序,对于⼀次遍历来说,每对对应线段之间的距离是已知的,那么我们需要解决的问题只有纵坐标的影响范围。

不妨把所有纵坐标都取出来,离散化映射到[1,t]的区间中的t的整数值,并把这些纵坐标表⽰为t-1段,其中第i段表⽰第i个纵坐标和第i+1个纵坐标之间的部分,然后⽤c[i]表⽰第i段被覆盖的次数。

这样就可以计算⾯积并,算法流程⼤致是这样:对于每⼀个线段,将其的k值累加到这个线段对应的若⼲个纵坐标区间计算⾯积:所有T−1个纵坐标区间对应的c值⼤于零的就说明这些部分的区间还存在,将存在的区间的长度累加起来,乘上当前线段与下⼀条线段之间的横坐标之差就是这两条线段之间的⾯积。

显然,这⾥就需要⽤到区间求和的操作。

这种事情,就丢给线段树吧!因为这道题中的区间修改都是成对出现的(+1/-1),所以不需要懒标记这个操作。

只需要在线段树的每个端点多维护两个值:cnt和len,分别记这段区间被覆盖的次数以及当前区间的纵坐标长度。

区域填充的扫描线算法

区域填充的扫描线算法

区域填充的扫描线算法区域填充是一种常见的计算机图形学算法,用于将一个封闭区域内的所有像素点填充为指定的颜色。

扫描线算法是区域填充的一种常用方法,本文将介绍扫描线算法的基本原理、实现步骤和一些优化技巧。

扫描线算法的基本原理是利用扫描线从图像的上边界向下扫描,检测每个扫描线与区域的交点。

当遇到一个交点时,根据该交点的左右两侧的交点情况,确定将该交点连接到哪个交点上。

通过不断地扫描和连接交点,最终将整个区域填充为指定的颜色。

下面是扫描线算法的具体实现步骤:1.首先需要确定区域的边界,可以由用户提供或通过其他算法生成。

边界可以用一系列的线段、多边形或曲线表示。

2. 创建一个数据结构来存储每个扫描线与区域的交点。

常用的数据结构是活性边表(Active Edge Table,AET)和扫描线填充表(Scanline Fill Table,SFT)。

AET用于存储当前扫描线与区域边界的交点,SFT用于存储所有扫描线的交点。

3.初始化扫描线的起始位置为图像的上边界,并创建一个空的AET。

4.开始扫描线的循环,直到扫描线到达图像的下边界。

每次循环都进行以下操作:-将扫描线与区域边界进行相交,找出所有与区域相交的线段,并将它们的交点加入到AET中。

-对AET按照交点的x坐标进行排序。

-从AET中取出相邻的两个交点,根据这两个交点之间的像素点是否在区域内来决定是否填充这些像素点。

5.当扫描线到达图像的下边界时,完成填充。

扫描线算法的实现可能会遇到一些边界情况和优化需求。

下面是一些常见的优化技巧:1.边界处理:在AET中存储的交点需要进行边界处理,确保交点处于图像范围内。

2.垂直线段处理:对于垂直线段,可以进行特殊处理,避免在AET中重复存储相同的交点。

3.区域内部边界处理:当区域内部有不连续的边界时,需要对交点进行合并,避免出现多余的像素点填充。

4.使用扫描线填充算法优化:对于大尺寸的区域填充,可以使用扫描线填充算法进行优化。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

© 2004 Dept. of Computer Science and Engineer
2018/11/22
3 / 56
多边形的扫描转换
扫描转换矩形(1/2):
void FillRectangle(Rectangle *rect,int color) { int x,y; for(y = rect->ymin; y <= rect->ymax; y++) for(x = rect->xmin; x <= rect->xmax; x++) PutPixel(x,y,color); }/*end of FillRectangle() */
2018/11/22
17 / 56
多边形的扫描转换:扫描线算法:
扫描线算法: - 交点的取整规则 要求:使生成的像素全部位 于多边形之内 - 用于线画图元扫描转换的 四舍五入原则导致部分像 素位于多边形之外,从而 不可用 假定非水平边与扫描线y=e相 交,交点的横坐标为x,规则 如下:
区域填充(扫描线算法)
•解决方法:当扫描线与多边形的顶 点相交时:
• 若共享顶点的两条边分别落在 扫描线的两边,交点只算一个; • 若共享顶点的两条边在扫描线 的同一边,这时交点作为零个或 两个。 •多边形边界上象素的取舍问题: •例:2×2图形填充:若不加处理 则变成3×3; •解决办法:下闭上开;左闭右开;
© 2004 Dept. of Computer Science and Engineer 16 / 56
2018/11/22
多边形的扫描转换:扫描线算法:
扫描线算法:
-
扫描线与边的交点类型: 第一类交点:新出现的边与扫描线的交点; 第二类交点:位于同一条边上的后继交点;
© 2004 Dept. of Computer Science and Engineer
© 2004 Dept. of Computer Science and Engineer 2018/11/22 23 / 56
多边形的扫描转换:扫描线算法:
•边表(Edge Table)的构造(2/2): •(3)每条边的数据形成一个结点,内容包括:该 扫描线与该边的初始交点x(即较低端点的x值), 1/k,以及该边的最大y值ymax。 x|ymin ymax 1/k NEXT •(4)同一桶中若干条边按X|ymin由小到大排序, 若X| ymin相等,则按照1/k由小到大排序。
© 2004 Dept. of Computer Science and Engineer
2018/11/22
20 / 56
多边形的扫描转换:扫描线算法:
扫描线算法:
-
交点的取整规则 规则3: 扫描线与多边形的顶点相交时,交点的取舍,保证交点正确配对。 解决方法: - 检查两相邻边在扫描线的哪一侧。 - 只要检查顶点的两条边的另外两个端点的Y值,两个Y值中大于交点Y 值的个数是0,1,2,来决定取0,1,2个交点。
© 2004 Dept. of Computer Science and Engineer
2018/11/22
21 / 56
多边形的扫描转换:扫描线算法:
•计算扫描线与多边形各边的交 点:最简单的方法: •将多边形的所有边放在一个 表中; •缺点:效率低 •改进的有效边表算法(Y连贯性 算法) •改进原理: •处理一条扫描线时,仅对有 效边求交; •利用扫描线的连贯性; •利用多边形边的连贯性;
© 2004 Dept. of Computer Science and Engineer
2018/11/22
19 / 56
多边形的扫描转换:扫描线算法:
扫描线算法:
-
交点的取整规则 规则2: - 边界上象素的取舍问题,避免填充扩大化; 解决方法: - 边界象素:规定落在右上边界的象素不予填充; - 具体实现时,只要对扫描线与多边形的相交区间左闭右开;
© 2004 Dept. of Computer Science and Engineer
2018/11/22
11 / 56ຫໍສະໝຸດ 多边形的扫描转换:扫描线算法:
扫描线算法:
-
目标:利用相邻像素之间的连贯性,提高算法效率; 处理对象:非自交多边形 (边与边之间除了顶点外无其它交点);
© 2004 Dept. of Computer Science and Engineer
2018/11/22
12 / 56
多边形的扫描转换:扫描线算法:
扫描线算法
基本思想:一条
扫描线与多边 形的边有偶数 个交点
© 2004 Dept. of Computer Science and Engineer
2018/11/22
13 / 56
区域填充(扫描线算法) 算法步骤:
(1)确定多边形所占有的最大扫描线数,得到多边形顶点的最小和最大y 值(ymin 和 ymax); (2)从y=ymin到y=ymax,每次用一条扫描线进行填充; (3)对一条扫描线填充的过程可分为四个步骤: a.求交:扫描线与各边的交点;
b.排序:按X大小对各交点排序;
c.交点配对:每对交点表示一个区间; d.区间填色:区间内置填充色;区间外填背景色;
© 2004 Dept. of Computer Science and Engineer
2018/11/22
14 / 56
区域填充(扫描线算法) 例:扫描线6的填充。 1、求交: A(2),B(3.5),C(7),D(11); 2、排序:
n
预处理; 离散计算方法:编码方法;
© 2004 Dept. of Computer Science and Engineer
2018/11/22
9 / 56
多边形的扫描转换
逐点判断法
•3)编码方法:累计角度方法的离散方法 Step: a.预处理,测试点在边上否? b.V为中点作局部坐标系,对象限按逆时针 (或顺时针)编码; P1 c.顶点编码Ipi, d.边编码。PiPi+1: △PiPi+1=Ipi+1-Ipi e.计算∑ △PiPi+1 (其中△PnPn+1 = △PnP0): 若 ∑ 为0, V在P外;若 ∑ 为+/-4,V 在 P内;
2018/11/22
2 / 56
区域填充
区域:点阵表示的图形,像素集合; 表示方法:内点表示、边界表示: - 内点表示:-》区域填充算法 枚举处区域内部的所有像素; 内部的所有像素填充同一个颜色; 边界像素填充与内部像素不同的颜色; - 边界表示:枚举出边界上所有的像素-》边界填充算法; 边界上的所有像素填充同一颜色; 内部像素填充与边界像素不同的颜色; 区域填充:对区域重新着色的过程,即从给定位置开始涂描直到指定 的边界条件为止; - 将指定的颜色从种子点扩展到整个区域的过程; - 区域填充算法要求区域是连通的; 一般步骤: - 确定那些像素位于填充图元的内部; - 确定以什么颜色填充这些像素;
P0
v P2
结论:逐点判断法程序简单,速度太慢,效率低。
© 2004 Dept. of Computer Science and Engineer 2018/11/22 10 / 56
多边形的扫描转换:扫描线算法:
-
几个概念:
边的连贯性:某条边与当前扫描线相交,也可能与下一条扫描 线相交; 扫描线的连贯性:当前扫描线与各边的交点顺序与下一条扫描 线与各边的交点顺序可能相同或类似; 区间连贯性:同一区间上的像素取同一颜色属性;
A(2),B(3.5),C(7),D(11);
3、交点配对: (0,2),(2,3.5),(3.5,7),(7 ,11),(11,以后);
存在问题:当扫描线与多边形顶点相交时,交点的取舍问题。如:扫描 线2正确,扫描线7错误。
© 2004 Dept. of Computer Science and Engineer 2018/11/22 15 / 56
© 2004 Dept. of Computer Science and Engineer 2018/11/22 22 / 56
多边形的扫描转换:扫描线算法: •活性边(Active Edge):指与当前扫描线相交的多边形的边,也称 为活性边。 •活性边表(Active Edge Table, AET):把活性边按与扫描线交点x 坐标递增的顺序存放在一个链表中,此链表称活性边表。
第四章 基本图形生成算法 (二)
© 2004 Dept. of Computer Science and Engineer
2018/11/22
主要内容:
直线的扫描转换
圆与椭圆的扫描算法
区域填充 线宽与线型的处理 字符 裁剪
反走样
© 2004 Dept. of Computer Science and Engineer
属于谁?
© 2004 Dept. of Computer Science and Engineer 2018/11/22 5 / 56
多边形的扫描转换
多边形的表示方法: - 顶点表示:用多边形的顶点序列刻划多边 形;
-
点阵表示:用位于多边形内象素的集合来 刻划多边形;
-
扫描转换多边形:将顶点表示形式转换成 点阵表示形式; 三种方法:逐点判断法;扫描线算法;边 缘填充法;
© 2004 Dept. of Computer Science and Engineer 2018/11/22 7 / 56
多边形的扫描转换
逐点判断法
•逐个判断绘图窗口内的像素: •如何判断点在多边形的内外关系? 1)射线法; 2)累计角度法; 3)编码法; •1)射线法 步骤: 1) 从待判别点v发出射线; 2) 求交点个数k; 3) K的奇偶性决定了点与多边形的内 外关系; 4)奇异情况处理;
相关文档
最新文档