区域填充算法区域填充算法

合集下载

实验三 区域填充算法的实现

实验三 区域填充算法的实现

实验三区域填充算法的实现一、实验目的和要求:1、掌握区域填充算法基本知识2、理解区域的表示和类型,能正确区分四连通和八连通的区域3、了解区域填充的实现原理,利用Microsoft Visual C++ 6.0或win-TC实现区域种子填充的递归算法。

二、实验内容:1、编程完成区域填色2、利用画线函数,在屏幕上定义一个封闭区域。

3、利用以下两种种子填充算法,填充上述步骤中定义的区域(1)边界表示的四连通区域种子填充的实现(2)内点表示的四连通区域种子填充的实现4、将上述算法作部分改动应用于八连通区域,构成八连通区域种子填充算法,并编程实现。

三、实验结果分析四连通图的实现:程序代码:#include<graphics.h>#include <conio.h>#include<math.h>#include<time.h>void BoundaryFill4(int x,int y,int Boundarycolor,int newcolor){if(getpixel(x,y) != newcolor && getpixel(x,y) !=Boundarycolor){putpixel(x,y,newcolor);Sleep(1);BoundaryFill4(x-1,y,Boundarycolor,newcolor);BoundaryFill4(x,y+1,Boundarycolor,newcolor);BoundaryFill4(x+1,y,Boundarycolor,newcolor);BoundaryFill4(x,y-1,Boundarycolor,newcolor);}}void polygon(int x0,int y0,int a,int n,float af){int x,y,i;double dtheta,theta;if(n<3)return;dtheta=6.28318/n;theta=af*0.0174533;moveto(x0,y0);x=x0;y=y0;for(i=1;i<n;i++){x=x+a*cos(theta);y=y+a*sin(theta);lineto(x,y);theta=theta+dtheta;}lineto(x0,y0);}void main(){int x=50,y=75;int a,b,c,d,i,j;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode," ");cleardevice();setcolor(RGB(0,255,0));setfillstyle(WHITE);polygon(x,y,60,5,0.);a=100;b=100;c=RGB(0,255,0);d=RGB(255,0,255);BoundaryFill4(a,b,c,d);getch();closegraph();}实验结果八连通的实现程序代码:#include<graphics.h>#include<conio.h>#include<time.h>#include <malloc.h>#include <windows.h>#define MaxSize 100typedef struct{int x;int y;}Seed,ElemType;typedef struct{ElemType data[MaxSize];int top; //栈顶指针} SqStack;void InitStack(SqStack *&s){s=(SqStack *)malloc(sizeof(SqStack));s->top=-1;}int StackEmpty(SqStack *s){return(s->top==-1);}int Push(SqStack *&s,ElemType e){if (s->top==MaxSize-1)return 0;s->top++;s->data[s->top]=e;return 1;}int Pop(SqStack *&s,ElemType &e){if (s->top==-1)return 0;e=s->data[s->top];s->top--;return 1;}void floodfill8(int x,int y,int oldcolor,int newcolor) {if(getpixel(x,y)==oldcolor){putpixel(x,y,newcolor);Sleep(2);floodfill8(x,y+1,oldcolor,newcolor);floodfill8(x,y-1,oldcolor,newcolor);floodfill8(x-1,y,oldcolor,newcolor);floodfill8(x+1,y,oldcolor,newcolor);floodfill8(x+1,y+1,oldcolor,newcolor);floodfill8(x+1,y-1,oldcolor,newcolor);floodfill8(x-1,y+1,oldcolor,newcolor);floodfill8(x-1,y-1,oldcolor,newcolor);}}void main(){int a,b,c,d,i,j;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode," "); cleardevice();setfillstyle(RGB(255,255,255));setcolor(GREEN);int points[]={320,200,270,290,370,290}; fillpoly(3,points);rectangle(500,420,100,100);a=RGB(255,255,255);b=RGB(255,0,0);floodfill8(320,240,a,b);c=RGB(0,0,0);d=RGB(0,0,255);floodfill8(320,180,c,d);getch();closegraph();}实验结果:2、结果分析:通过以上各算法运行结果分析与对比可知:1.四连通算法的缺点是有时不能通过狭窄区域,因而不能填满多边形。

c语言多边形区域填充算法

c语言多边形区域填充算法

c语言多边形区域填充算法C语言多边形区域填充算法一、介绍多边形区域填充算法是计算机图形学中的一项重要技术,用于将给定的多边形区域进行填充,使其呈现出丰富的颜色或纹理,增强图形的效果和表现力。

本文将介绍一种常用的C语言多边形区域填充算法——扫描线填充算法。

二、扫描线填充算法原理扫描线填充算法是一种基于扫描线的填充方法,其基本思想是将多边形区域按照水平扫描线的顺序,从上到下逐行扫描,通过判断扫描线与多边形边界的交点个数来确定是否进入多边形区域。

具体步骤如下:1. 首先,确定多边形的边界,将其存储为一个边表。

边表中的每个边都包含起点和终点的坐标。

2. 创建一个活性边表(AET),用于存储当前扫描线与多边形边界的交点。

初始时,AET为空。

3. 从上到下逐行扫描多边形区域,对每一条扫描线,从边表中找出与该扫描线相交的边,并将其加入AET中。

4. 对于AET中的每一对交点,按照从左到右的顺序两两配对,形成水平线段,将其填充为指定的颜色或纹理。

5. 在扫描线的下一行,更新AET中的交点的坐标,然后重复步骤4,直到扫描到多边形区域的底部。

三、代码实现下面是一个简单的C语言实现扫描线填充算法的示例代码:```#include <stdio.h>#include <stdlib.h>#include <stdbool.h>typedef struct {int x;int y;} Point;typedef struct {int yMax;float x;float dx;int next;} Edge;void fillPolygon(int n, Point* points, int color) {// 获取多边形的边界int yMin = points[0].y;int yMax = points[0].y;for (int i = 1; i < n; i++) {if (points[i].y < yMin) {yMin = points[i].y;}if (points[i].y > yMax) {yMax = points[i].y;}}// 创建边表Edge* edges = (Edge*)malloc(sizeof(Edge) * n);int k = n - 1;for (int i = 0; i < n; i++) {if (points[i].y < points[k].y) {edges[i].yMax = points[k].y;edges[i].x = points[i].x;edges[i].dx = (float)(points[k].x - points[i].x) / (points[k].y - points[i].y);edges[i].next = k;} else {edges[i].yMax = points[i].y;edges[i].x = points[k].x;edges[i].dx = (float)(points[i].x - points[k].x) / (points[i].y - points[k].y);edges[i].next = i;}k = i;}// 扫描线填充for (int y = yMin; y < yMax; y++) {int xMin = INT_MAX;int xMax = INT_MIN;for (int i = 0; i < n; i++) {if (y >= edges[i].yMax) {continue;}edges[i].x += edges[i].dx;if (edges[i].x < xMin) {xMin = edges[i].x;}if (edges[i].x > xMax) {xMax = edges[i].x;}int j = edges[i].next;while (j != i) {edges[j].x += edges[j].dx; if (edges[j].x < xMin) {xMin = edges[j].x;}if (edges[j].x > xMax) {xMax = edges[j].x;}j = edges[j].next;}}for (int x = xMin; x < xMax; x++) { drawPixel(x, y, color);}}free(edges);}int main() {// 定义多边形的顶点坐标Point points[] = {{100, 100},{200, 200},{300, 150},{250, 100}};// 填充多边形区域为红色fillPolygon(4, points, RED);return 0;}```四、总结通过扫描线填充算法,我们可以实现对多边形区域的填充,从而提升图形的表现效果。

区域填充算法范文

区域填充算法范文

区域填充算法范文
常见的区域填充算法有种子填充算法和扫描线填充算法。

种子填充算法是一种递归算法,从指定的种子点开始,将其颜色设为
目标颜色,并继续填充其相邻的像素点,直到所有相邻的像素点都被填充
为目标颜色。

这个过程可以通过递归或者使用栈进行实现。

种子填充算法
的优点是简单易懂,但对于复杂的区域存在堆栈溢出的风险。

扫描线填充算法利用了图形中连续的扫描线和区域的边界特性。

首先,确定区域的上下边界,然后对每一条扫描线从左往右进行遍历。

当扫描线
与区域的边界相交时,根据交点的颜色决定当前像素点的填充颜色。

该算
法可以通过判断相邻像素点的颜色是否相同来确定区域的边界。

为了提高算法的效率,可以使用填充算法的优化技术。

例如,使用堆
栈数据结构来存储需要填充的像素点,避免了递归过程中的堆栈溢出问题。

另外,可以使用四邻域或八邻域填充算法来决定像素点的相邻关系,减少
算法的时间复杂度。

总之,区域填充算法是图形学和图像处理中的重要算法之一,通过将
指定的区域填充为指定的颜色,实现了各种复杂任务的自动化处理和可视
化展示。

随着计算机技术的发展,区域填充算法的应用前景将会更加广泛,并且不断出现新的算法和优化技术,提高填充效率和质量。

区域填充算法

区域填充算法

区域填充算法⼀、区域填充概念区域:指已经表⽰成点阵形式的填充图形,是象素的集合。

区域填充:将区域内的⼀点(常称种⼦点)赋予给定颜⾊,然后将这种颜⾊扩展到整个区域内的过程。

区域填充算法要求区域是连通的,因为只有在连通区域中,才可能将种⼦点的颜⾊扩展到区域内的其它点。

1、区域有两种表⽰形式1. 内点表⽰:枚举出区域内部的所有象素内部所有象素着同⼀个颜⾊边界像素着与内部象素不同的颜⾊。

2. 边界表⽰:枚举出区域外部的所有象素边界上的所有象素着同⼀个颜⾊内部像素着与边界象素不同的颜⾊。

2、区域连通1. 四向连通区域:从区域上⼀点出发可通过上、下、左、右四个⽅向移动的组合,在不越出区域的前提下,到达区域内的任意象素。

2. ⼋向连通区域:从区域上⼀点出发可通过上、下、左、右、左上、右上、左下、右下⼋个⽅向移动的组合,在不越出区域的前提下,到达区域内的任意象素。

3. 四连通与⼋连通区域的区别连通性:四连通可以看作⼋连通的⾃⼰,但是对边界有要求⼆、简单种⼦填充算法1、基本思想给定区域G⼀种⼦点(x, y),⾸先判断该点是否是区域内的⼀点,如果是,则将该点填充为新的颜⾊,然后将该点周围的四个点(四连通)或⼋个点(⼋连通)作为新的种⼦点进⾏同样的处理,通过这种扩散完成对整个区域的填充。

这⾥给出⼀个四连通的种⼦填充算法(区域填充递归算法),使⽤【栈结构】来实现原理算法原理如下:种⼦像素⼊栈,当【栈⾮空】时重复如下三步:2、算法代码这⾥给出⼋连通的种⼦填充算法的代码:void flood_fill_8(int[] pixels, int x, int y, int old_color, int new_color) { if (x < w && x > 0 && y < h && y > 0) {// 如果是旧的颜⾊⽽且还没有给他填充过if (pixels[y * w + x] == old_color) {// 填充为新的颜⾊pixels[y * w + x]== new_color);// 递归flood_fill_8(pixels, x, y + 1, old_color, new_color);flood_fill_8(pixels, x, y - 1, old_color, new_color);flood_fill_8(pixels, x - 1, y, old_color, new_color);flood_fill_8(pixels, x + 1, y, old_color, new_color);flood_fill_8(pixels, x + 1, y + 1, old_color, new_color);flood_fill_8(pixels, x + 1, y - 1, old_color, new_color);flood_fill_8(pixels, x - 1, y + 1, old_color, new_color);flood_fill_8(pixels, x - 1, y - 1, old_color, new_color);}}}3、OpenCV实现import cv2def seed_fill(img):ret, img = cv2.threshold(img, 128, 255, cv2.THRESH_BINARY_INV) label = 100stack_list = []h, w = img.shapefor i in range(1, h-1, 1):for j in range(1, w-1, 1):if (img[i][j] == 255):img[i][j] = labelstack_list.append((i, j))while len(stack_list) != 0:cur_i = stack_list[-1][0]cur_j = stack_list[-1][1]img[cur_i][cur_j] = labelstack_list.remove(stack_list[-1])# 四邻域,可改为⼋邻域if (img[cur_i-1][cur_j] == 255):stack_list.append((cur_i-1, cur_j))if (img[cur_i][cur_j-1] == 255):stack_list.append((cur_i, cur_j-1))if (img[cur_i+1][cur_j] == 255):stack_list.append((cur_i+1, cur_j))if (img[cur_i][cur_j+1] == 255):stack_list.append((cur_i, cur_j+1))cv2.imwrite('./result.jpg', img)cv2.imshow('img', img)cv2.waitKey()if __name__ == '__main__':img = cv2.imread('./test.jpeg', 0)seed_fill(img)4、简单种⼦填充算法的优点和缺点优点:1. 该算法也可以填充有孔区域缺点:1. 有些像素会多次⼊栈,降低算法效率,栈结构占空间2. 递归执⾏,算法简单,但效率不⾼,区域内每⼀像素都要进/出栈,费时费内存3. 改进算法,减少递归次数,提⾼效率三、扫描线种⼦填充算法⽬标:减少递归层次适⽤于边界表⽰的4连通区间1、基本思想在任意不间断区间中只取⼀个种⼦像素(不间断区间指在⼀条扫描线上⼀组相邻元素),填充当前扫描线上的该段区间;然后确定与这⼀区段相邻的上下两条扫描线上位于区域内的区段,并依次把它们保存起来,反复进⾏这个过程,直到所保存的各个区段都填充完毕。

cad 区域填充的算法

cad 区域填充的算法

cad 区域填充的算法
CAD区域填充是一种用于计算机辅助设计软件中的算法,用于在指定区域内填充颜色。

这个算法基于扫描线填充方法,它从图形的顶部开始
扫描,逐行地将颜色填充到区域中。

具体而言,CAD区域填充算法可以通过以下步骤来实现:
1. 选择一个起始点,并确保该点位于待填充区域内。

2. 在当前扫描线上,从起始点开始向左和向右移动,找到左和右边界。

这可以通过检测不同颜色或图形边界来确定。

3. 填充当前扫描线的像素点,从左边界到右边界之间的像素。

4. 移动到下一行,通过向下移动一行并在新的扫描线上重复步骤2和
步骤3,直到所有行都被处理完毕或者遇到边界。

5. 当遇到边界或结束时,停止填充过程。

需要注意的是,在实际应用中,为了提高效率和减少计算量,可以使
用一些优化策略来加速CAD区域填充算法的执行,例如边界框剪裁和
扫描线段合并。

总之,CAD区域填充算法是一种实现图形填充的重要方法,它可以在计算机辅助设计软件中帮助用户快速填充指定区域并实现更好的可视化
效果。

区域填充算法的实现

区域填充算法的实现

区域填充算法的实现实现区域填充算法的一种常见方法是使用递归。

以下是一个使用递归实现的区域填充算法的伪代码:1. 定义函数fillPixel(x, y, targetColor, fillColor):-如果像素点(x,y)的颜色与目标颜色相同,将其颜色修改为填充颜色。

-否则,返回。

2. 定义函数regionFill(x, y, targetColor, fillColor):-如果像素点(x,y)的颜色与目标颜色相同,返回。

- 否则,调用fillPixel(x, y, targetColor, fillColor)。

- 递归调用regionFill(x-1, y, targetColor, fillColor)。

- 递归调用regionFill(x+1, y, targetColor, fillColor)。

- 递归调用regionFill(x, y-1, targetColor, fillColor)。

- 递归调用regionFill(x, y+1, targetColor, fillColor)。

3. 调用regionFill(seedX, seedY, targetColor, fillColor)。

在上述算法中,fillPixel函数用于将特定颜色填充到像素点(x, y)。

regionFill函数使用递归的方式遍历相邻的像素点,并对目标颜色的像素点调用fillPixel函数。

seedX和seedY表示种子像素点的坐标,targetColor表示目标颜色,fillColor表示填充颜色。

实现区域填充算法时还需要考虑以下几个问题:1.像素点的表示:图像可以由二维数组表示,其中每个元素表示一个像素点的颜色。

2.填充颜色选择:填充颜色可以由RGB值表示,或者在预定义的颜色集合中选择。

3.边界处理:对于位于图像边界上的种子像素点,需要特殊处理以防止数组越界错误。

4.递归终止条件:填充算法使用递归,需要定义递归终止的条件,以防止无限递归。

第3章 填充

第3章 填充

3.5.2 多边形域填充 常用的填充方法是按扫描线顺序,计算扫描线 与多边形的相交区间,再用要求的颜色显示这些区 间的像素,即完成填充工作,简称为扫描线填充算 法。区间的端点可以通过计算扫描线与多边形边界 线的交点获得,该方法适用于自动填充。
1.多边形域的填充步骤 一般多边形的填充过程,对于一条扫描线,可以分为 4个步骤: (1) 求交:计算扫描线与多边形各边的交点。 (2) 排序:把所有交点按x递增顺序进行排序。 (3) 交点配对:第1个与第2个,第3个与第4个等两两配对, 每对交点就代表扫描线与多边形的一个相交区间。 (4) 区间填色:把这些相交区间内的像素置成多边形颜色。
对例3.4重新使用改进后的简单种子填充算法步骤如下。 解: (1) 种子像素(3, 2)入栈并着色。 (2) 出栈(3, 2)。入栈(2, 2)、(3, 3)、(4, 2)、(3, 1)并着色。 (3) 出栈(3, 1)。入栈(2, 1)、(4, 1)并着色。 (4) 出栈(4, 1)。 (5) 出栈(2, 1)。 (6) 出栈(4, 2)。 (7) 出栈(3, 3)。入栈(2, 3)并着色。 (8) 出栈(2, 3)。 (9) 出栈(2, 2)。入栈(1, 2)并着色。 (10) 出栈(1, 2),栈空结束。
3.5 区域填充
3.5.1 种子填充算法
(1) 内定义区域:区域内所有像素着相同颜色,区 域外像素着另一种颜色。区域填充是将区域内所有 像素的颜色置为新颜色。这种填充又称为泛填充, 如图3-46所示。
图3-46 区域的内点表示
(2) 边界定义区域:区域边界像素着特定颜色,区 域内像素不取特定颜色。区域填充是将区域内所有 像素的颜色置为边界像素颜色或新颜色。这种填充 称为边界填充,如图3-47所示。

区域填充算法

区域填充算法

7
9 9
9
对边界和内点表示的八连通区域的填充,只要将上述算法的对四 个像素点填充改为八个像素点即可。 四连通区域种子填充算法的缺点是有时不能通过狭窄区域区域, 因而不能填满多边形。八连通算法的缺点是有时会填出多边形的 边界。由于填不满比涂出更容易补救,因此四连通算法比八连通 算法用得更多。
(3)扫描线种子填充算法
(2)内点表示的四连通区域种子填充算法
基本思想:从多边形内部任一点(像素)出发,按照“右 上左下”的顺序判断相邻像素,若是区域内的像素,则对 其填充,并重复上述过程,直至所有像素填充完毕。 可以使用栈结构来实现该算法,种子像素入栈,档栈非空, 重复执行下面操作: 1)栈顶像素出栈; 2)将出栈像素置成多边形填充的颜色;
基本思想:从多边形内部任一点(像素)出发,按照 “右上左下”的顺序判断相邻像素,若不是边界像素 且没被填充过,则对其填充,并重复上述过程,直至 所有像素填充完毕。 可以使用栈结构来实现该算法,种子像素入栈,档栈 非空,重复执行下面操作: 1)栈顶像素出栈; 2)将出栈像素置成多边形填充的颜色; 3)按“右上左下”的顺序检查与出栈像素相邻的四个 像素,若其中某个像素不在边界上且未置成多边形色, 则把该像素入栈。
扫描线算法分析(举例分析)
基本思想:在任意不间断的区间中只取一个像素(不 间断区间指一条扫描线上的一组相邻元素),填充当 前扫描线上的该段区间,然后确定与这一段相邻的上 下两条扫描线位于区域内的区段,并依次把它们保存 起来,反复进行这个过程,指导所有保存的每个区段 都填充完毕。
(3)扫描线种子填充算法
种子像素入栈,当栈非空时,重复以下步骤: (1)栈顶像素出栈 (2)沿扫描线对出栈像素的左右像素进行填充, 直到遇到边界像素为止 (3)将上述区间内最左、最右像素记为xl 和xr (4)在区间[xl ,xr]中检查与当前扫描线相邻的上 下两条扫描线是否全为边界像素、或已填充 的像素,若为非边界、未填充的像素,则把 每一区间的最右像素取为种子像素入栈
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

简单方程产生圆弧
圆的极坐标方程为:
x R cos y R sin
i 1 i (为一固定角度步长 ) xi 1 round( R cos i 1 ) yi 1 round( R sin i 1 )
30
中点Bresenham画圆
给定圆心在原点,半径为整数R的圆,其方程为
17
D 2xd 2x ( d k ) D 2y
中点Bresenham算法——算法步骤
输入直线的两端点P0(x0,y0)和P1(x1,y1)。
计算初始值△x、△y、D=△x-2△y、x=x0、y=y0。
绘制点(x,y)。判断D的符号。若D<0,则(x,y)更 新 为 ( x+1,y+1),D 更 新 为 D+2△x-2△y; 否 则 (x,y)更新为(x+1,y), D更新为D-2△y。 当直线没有画完时,重复上一步骤,否则结束。 程序演示
9
中点Bresenham算法
算法原理:根据直线的斜率确定或选择变量在 x或y方向上每次递增一个单位,而另一方向的 增量为1或0,它取决于实际直线与相邻象素点
的距离,这一距离称为误差项。
10
假定0≤k≤1, 即0≤ Δy/Δ x ≤1,x是最大位移方向
Pu(xi+1,yi+1) Q M(xi+1,yi+1/2) P(xi,yi) Pd(xi+1,yi)
(x0+1,y0+0.5) (x0,y0)
图5.9 计算初值
16
中点Bresenham算法——改进
改进:用2d△x代替d ,令D=2d△x 则:
D0 2xd0 2x (0.5 k ) x 2y d 0 D0 D 2xd 2x ( d 1 k ) 2xd 2x 2y D 2x 2y d 0 D0
图5.8 误差项递推
d 2 F ( xi 2, yi 0.5) yi 0.5 k ( xi 2) b
d1 k d 2 yi 0.5 k ( xi 1) b k
中点Bresenham算法
初始值d的计算
d 0 F ( x0 1, y0 0.5) y0 0.5 k ( x0 1) b y0 kx0 b k 0.5 0.5 k
2
2 2
( xi 2) ( yi 1.5) R
2 2 2
xi
2
xi+1 xi+2
d 2 ( xi 1 1) ( yi 0.5 1) R
2
图5.15 d>0的情况
2
( xi 1) 2 xi 3 ( yi 0.5) 2( yi 0.5) 1 R ( xi 1) ( yi 0.5) 2( xi yi ) 5 d1 2( xi yi ) 5
21
改进1:令e=d-0.5
xi 1 xi 1 y yi 1 i 1 yi (d 0.5) (d 0.5)
xi 1 xi 1 y yi 1 i 1 yi
(e 0) (e 0)
误差项的计算 • d初=0, • 每走一步:d=d+k • if (e>0) then d=d-1
8
中点Bresenham算法
直线的方程
y y1 y0 F ( x, y) y kx b 0 , 其中k x x1 x0
y F(x,y)=0 F(x,y)>0 F(x,y)<0 x F(x,y)<0 F(x,y)=0 F(x,y)>0 x y
图5.3 直线将平面分为三个区域
中点Bresenham画圆
判别式的初始值
d 0 F ( x0 1, y0 0.5) F (1, R 0.5) 1 ( R 0.5) R
2 2
1.25 R
36
改进:用d-0.25代替d
此时有:
d d 2 xi 3 d0 1 R
d 0.25 d 0.25
图5.7 误差项递推
d 2 yi 0.5 k ( xi 1) b 1 k d1 1 k
误差项的递推(d≥0)
d1 F ( xi 1, yi 0.5) yi 0.5 k ( xi
(x i+2,yi+0.5) 1) b (xi+1,yi+0.5) (xi,yi) d>=0
2
图形生成的概念
图形的生成:是在指定的
输出设备上,根据坐标描
述构造二维几何图形。
图形的扫描转换:在光栅
显示器等数字设备上确定
图5.1 用象素点集逼近直线
一个最佳逼近于图形的象
素集的过程。
3
5.1 直线的扫描转换
直线的绘制要求
(1)直线要直; (2)直线的端点要准确,无定向性无断裂; (3)直线的亮度、色泽要均匀; (4)画线的速度要快; (5)具有不同的色泽、亮度、线型等。
y y=x R
x
图5.12 1/8圆弧
27
圆的扫描转换
简单方程生成圆弧
中点Bresenham算法
28
简单方程产生圆弧
算法原理:利用其函数方程,直接离散计算。 圆的函数方程为: x
2
y R
2
2
xi1 xi 1
x 0, R
2 2 i 1

2

(5 - 7)
29
yi1 round( R x )
max(|△x|,|△y|)=|△y|,此时|k|≥1:
1 1 xi 1 xi x xi x xi y k 1 yi 1 yi y yi y yi 1 y
数值微分法(DDA法)——特点
增量算法 直观、易实现 不利于用硬件实现
第五章 基本图形生成算法
如何指定的输出设备上根据坐标描述构造基 本二维几何图形(点、直线、圆、椭圆、多边 形域、字符串及其相关属性等)。
1
第五章 基本图形生成算法
图形生成的概念 直线段的扫描转换 圆的扫描转换 多边形的扫描转换与区域填充 属性处理
反走样技术
在OpenGL中绘制图形
图5.14 d≤0的情况
2
d 2 ( xi 1 1) ( yi 0.5) R
2 2 2
( xi 1) 2 xi 3 ( yi 0.5) R d1 2 xi 3
yi
P
误差项的递推(d>0)
yi-1 yi-2
2 2
d 2 F ( xi 2, yi 1.5)
x y R
2 2
2
构造函数F(x,y)=x2+y2-R2。 对于圆上的点,有F(x,y)=0; 对于圆外的点,F(x,y)>0; 而对于圆内的点,F(x,y)<0。
31
y
Pu P M Pd
x
图5.13 中点Bresenham画圆的原理
中点Bresenham画圆
构造判别式:
d F ( xM , yM ) F ( xi 1, yi 0.5) ( xi 1)2 ( yi 0.5)2 R2
改进的Bresenham算法——算法步骤
1.输入直线的两端点P0(x0,y0)和P1(x1,y1)。 2.计算初始值△x、△y、e=-△x、x=x0、y=y0。 3.绘制点(x,y)。 4.e更新为e+2△y,判断 e的符号。若e>0,则 (x,y) 更新为(x+1,y+1),同时将e更新为e-2△x;否则 (x,y)更新为(x+1,y)。
当d≤0时,下一点取Pu(xi +1,yi); 当d>0时,下一点取Pd(xi +1,yi-1)。
33
yi
P
误差项的递推(d≤0)
yi-1 yi-2 xi
2 2
d 2 F ( xi 2, yi 0.5)
( xi 2)2 ( yi 0.5)2 R 2
xi+1 xi+2
图5.4 Brensemham算法生成直线的原理
判别式:
d F ( xM , yM ) F ( xi 1, yi 0.5) yi 0.5 k ( xi 1) b
则有:
xi1 xi 1 yi 1 yi1 y i
(d 0) (d 0)
y
yi+1 ε△y yi xi ε△x xi+1 x
xi 1 xi x yi 1 yi y
ε=1/max(|△x|,|△y|)
图5.2 DDA算法原理
6
max(|△x|,|△y|)=|△x|,即|k|≤1的情况:
1 xi 1 xi x xi x xi 1 x 1 yi 1 yi y yi y yi k x
图5.6 Brensemham算法生成直线的原理
误差项的递推(d<0)
d1 F ( xi 1, yi 0.5) yi 0.5 k ( xi 1) b
d 2 F ( xi 2, yi 1.5) yi 1.5 k ( xi 2) b
(x i+2,yi+1.5) (xi+1,yi+0.5) (xi,yi) d<0
5.当直线没有画完时,重复步骤3和4。否则结束。
相关文档
最新文档