直线生成算法
计算机图形学实验二:直线的生成算法的实现

实验二: 直线的生成算法的实现班级 08信计2班学号 20080502055 姓名分数一、实验目的和要求:1.理解直线生成的原理;2.掌握几种常用的直线生成算法;3.利用C实现直线生成的DDA算法。
二、实验内容:1.了解直线的生成原理2、掌握几种基本的直线生成算法: DDA画线法、中点画线法、Bresenham画线法。
3、仿照教材关于直线生成的DDA算法, 编译程序。
4.调试、编译、运行程序。
三、实验过程及结果分析1.直线DDA算法:算法原理:已知过端点P0(x0,y0), P1(x1,y1)的直线段L(P0,P1), 斜率为k=(y1-y0)/(x1-x0), 画线过程从x的左端点x0开始, 向x右端点步进, 步长为1个像素, 计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,yi+1=yi+k, 即当x每递增1, y递增k。
由计算过程可知, y与k可能为浮点数, 需要取y整数, 源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
(1)程序代码:#include"stdio.h"#include"graphics.h"void linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;setbkcolor(7);}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,"");a=100;b=100;c=200;d=300;e=5;linedda(a,b,c,d,e);getch();closegraph();}运行结果:2.中点画线算法:假定所画直线的斜率为k∈[0,1], 如果在x方向上增量为1, 则y方向上的增量只能在0~1之间。
直线生成算法——Bresenham法

直线生成算法——Bresenham法最近的研究涉及在像素图上作直线,自己也不想花时间摸索,于是在网上找到了Bresenham的直线生成算法,有一篇博客讲得清晰明了,但是算法上有些问题,我进行了改进和移植,下面讲解Bresenham的直线生成算法时也是参考这篇博文。
1.算法简介图1算法思想:图1中,连接M点和N点的直线经过点B,由于是像素图,所以实际上B 点应该由A点或者C点代替。
当B点更靠近A点时,选择点A(x+1,y+1);当B点更靠近C点时,选择点C(x+1,y)。
因此,当ε+m < 0.5时,绘制(x + 1, y)点,否则绘制(x + 1, y + 1)点,这里ε为累加误差,表达式为:式中:表示在第n次计算时的值,表示在第n+1次计算时的值;m就是直线的斜率。
由于斜率m的值有正有负,有可能为0,也可能为∞,为了避免分别讨论这些情况,将上述公式两边都乘以dx, 并将ε*dx用ξ表示,则有式中:表示在第n次计算时的值,表示在第n+1次计算时的值;dx为起点和终点横坐标之差,dy为起点和终点纵坐标之差。
还需说明一点,由直线斜率的定义故值得注意的是,现在我们只考虑dx > dy,且x,y的增量均为正的情况,但实际上有8种不同的情况(但是算法思想不变),如图2所示如图22.算法程序前文提到的那篇博文提出了一种方法,能将这8种情况都考虑,很巧妙。
但是实际应用时发现程序运行结果不是完全对,多次检查之后将程序进行了修改。
修改后的算法VB程序如下‘**************************************************************************** Type mypos '自定义数据类型x As Integery As IntegerEnd Type‘**************************************************************************** Function Bresenham(arr() As mypos, x1, y1, x2, y2)Dim x!, y!, dx!, dy!, ux%, uy%, eps!Dim cnt%ReDim arr(100)dx = x2 - x1dy = y2 - y1If dx >= 0 Then ux = 1If dx < 0 Then ux = -1If dy >= 0 Then uy = 1If dy < 0 Then uy = -1x = x1y = y1eps = 0dx = Abs(dx): dy = Abs(dy)cnt = 0If dx >= dy ThenFor x = x1 To x2 Step uxcnt = cnt + 1If 2 * (eps + dy) < dx Theneps = eps + dyarr(cnt).x = xarr(cnt).y = yElseeps = eps + dy - dxIf cnt >= 2 Then y = y + uy 'cnt大于2才执行y = y + uy,即排除起始坐标点,否则造成错误结果arr(cnt).x = xarr(cnt).y = yEnd IfNext xElseFor y = y1 To y2 Step uycnt = cnt + 1If 2 * (eps + dx) < dy Theneps = eps + dxarr(cnt).x = xarr(cnt).y = yElseeps = eps + dx - dyIf cnt >= 2 Then x = x + ux 'cnt大于2才执行x = x + ux,即排除起始坐标点,否则造成错误结果arr(cnt).x = xarr(cnt).y = yEnd IfNext yEnd Ifarr(0).x = cnt’记录元素个数End Function如果大家有不同看法,还希望共同讨论3.程序运行结果(VB+ OpenGL)图3图4绘制y=x,0≤x≤10,图3是原程序运行结果,图4时修改后的程序运行结果,原程序运行得到的起点是(0,1),但实际应该是(0,0)图5图6绘制直线[第1个坐标为起点,第2个坐标为终点](5,5)-(15,15)、(5,10)-(15,15)、(5,15)-(15,15)、(5,20)-(15,15)、(5,25)-(15,15);(25,5)-(15,15)、(25,10)-(15,15)、(25,15)-(15,15)、(25,20)-(15,15)、(25,25)-(15,15);(5,5)-(15,15)、(10,5)-(15,15)、(15,5)-(15,15)、(20,5)-(15,15)、(25,5)-(15,15);(5,25)-(15,15)、(10,25)-(15,15)、(15,25)-(15,15)、(20,25)-(15,15)、(25,25)-(15,15);图5是原程序运行结果,图6是修改后的程序运行结果。
分别解释直线生成算法dda法,中点画线法和bresenham法的基本原理

分别解释直线生成算法dda法,中点画线法和
bresenham法的基本原理
直线生成算法DDA法、中点画线法和Bresenham法的基本原理如下:
1. DDA直线生成算法:基于差分运算的直线生成算法。
通过将直线分割成
若干个相邻的像素点,并按照一定的步长进行逐点绘制,实现直线的绘制。
算法主要涉及到线性插值的思想,即根据已知的两点坐标,通过计算它们之间的差值,然后根据这个差值和步长来确定新的像素点的位置。
2. 中点画线法:一种线段绘制算法,从线段的起点和终点出发,按照一定的规则向终点逐步逼近,并在途中以控制变量的方式得出每个像素点的坐标,从而绘制出所需的线条。
具体实现中,通过计算线段斜率的变化情况,分为斜率小于1和大于等于1两种情况,并采用Bresenham的对称性原理,以中点的颜色来控制每个像素点的生长方向,从而获得较高的绘制效率和图像质量表现。
3. Bresenham算法:通过一系列的迭代来确定一个像素点是否应该被绘制。
对于一条从点(x1,y1)到点(x2,y2)的直线,首先计算出斜率k。
然后,通过比较每个像素点的y值到直线上的y值,来决定哪些像素点应该被绘制。
当斜率k大于等于1时,在x方向上迭代,而对于每个x值,计算出y值,并将像素点(x,y)绘制。
当斜率k小于1时,在y方向上迭代,而对于每个y值,计算出x值,并将像素点(x,y)绘制。
以上内容仅供参考,如需更多信息,建议查阅相关文献或咨询数学专业人士。
计算机图形学实验二 直线的生成算法的实现

实验二直线的生成算法的实现班级 08信计二班学号 20080502086 姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、熟悉直线的生成算法,掌握直线的绘制3、实现直线生成的DDA 中点画法 Bresenham算法4、了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在试验设计集成下进行图形处理程序的设计方法二、实验内容:1、了解直线生成的原理直线DDA算法,中点画线算法,Bresenham画线算法2、编程实现DDA算法、Bresenham算法、中点画法绘制直线段三、实验结果分析1.DDA算法// 程序名称:基于 DDA 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 四舍五入int Round(float x){return (int)(x < 0 ? x - 0.5 : x + 0.5);}// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_DDA(int x1, int y1, int x2, int y2, int color){float x, y; // 当前坐标点float cx, cy; // x、y 方向上的增量int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);x = (float)x1;y = (float)y1;cx = (float)(x2 - x1) / steps;cy = (float)(y2 - y1) / steps;for(int i = 0; i < steps; i++){putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画一个 color 颜色的点x += cx;y += cy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_DDA(100, 1, 1, 478, GREEN);Line_DDA(1, 478, 638, 1, GREEN);// 按任意键退出getch();closegraph();}2.中点算法// 程序名称:基于中点算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Midpoint(int x1, int y1, int x2, int y2, int color){int x = x1, y = y1;int a = y1 - y2, b = x2 - x1;int cx = (b >= 0 ? 1 : (b = -b, -1));int cy = (a <= 0 ? 1 : (a = -a, -1));putpixel(x, y, color);int d, d1, d2;if (-a <= b) // 斜率绝对值 <= 1{d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);while(x != x2){if (d < 0)y += cy, d += d2;elsed += d1;x += cx;putpixel(x, y, color);}}else // 斜率绝对值 > 1{d = 2 * b + a;d1 = 2 * b;d2 = 2 * (a + b);while(y != y2){if(d < 0)d += d1;elsex += cx, d += d2;y += cy;putpixel(x, y, color);}}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Midpoint(100, 1, 1, 478,YELLOW);Line_Midpoint(1, 478, 638, 1, YELLOW);// 按任意键退出getch();closegraph();}3. Bresenham 算法// 程序名称:基于 Bresenham 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Bresenham(int x1, int y1, int x2, int y2, int color){int x = x1;int y = y1;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int s1 = x2 > x1 ? 1 : -1;int s2 = y2 > y1 ? 1 : -1;bool interchange = false; // 默认不互换 dx、dyif (dy > dx) // 当斜率大于 1 时,dx、dy 互换{int temp = dx;dx = dy;dy = temp;interchange = true;}int p = 2 * dy - dx;for(int i = 0; i < dx; i++){putpixel(x, y, color);if (p >= 0){if (!interchange) // 当斜率 < 1 时,选取上下象素点y += s2;else // 当斜率 > 1 时,选取左右象素点x += s1;p -= 2 * dx;}if (!interchange)x += s1; // 当斜率 < 1 时,选取 x 为步长elsey += s2; // 当斜率 > 1 时,选取 y 为步长p += 2 * dy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Bresenham(100, 1, 1, 478, RED);Line_Bresenham(1, 478, 638, 1, RED);// 按任意键退出getch();closegraph();}实验结果分析三种算法运算结果比较:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法。
直线的Bresenham算法

生成直线的B resenham算法从上面介绍的DDA算法可以看到,由于在循环中涉及实型数据的加减运算,因此直线的生成速度较慢。
在生成直线的算法中,B resenham算法是最有效的算法之一。
B resenham算法是一种基于误差判别式来生成直线的方法。
一、直线Bresenham算法描述:它也是采用递推步进的办法,令每次最大变化方向的坐标步进一个象素,同时另一个方向的坐标依据误差判别式的符号来决定是否也要步进一个象素。
我们首先讨论m=△y/△x,当0≤m≤1且x1<x2时的B resenham算法。
从DDA直线算法可知这些条件成立时,公式(2-2)、(2-3)可写成:x i+1=x i+△x(2-2)y i+1=y i+△y(2-3)x i+1=x i+1 (2-6)y i+1=y i+m(2-7)有两种B resenham算法思想,它们各自从不同角度介绍了B resenham算法思想,得出的误差判别式都是一样的。
二、直线B resenham算法思想之一:由于显示直线的象素点只能取整数值坐标,可以假设直线上第i个象素点坐标为(x i,y i),它是直线上点(x i,y i)的最佳近似,并且x i=x i(假设m<1),如下图所示。
那么,直线上下一个象素点的可能位置是(x i+1,y i)或(x i+1,y i+1)。
由图中可以知道,在x=x i+1处,直线上点的y值是y=m(x i+1)+b,该点离象素点(x i+1,y i)和象素点(x i+1,y i+1)的距离分别是d1和d2:这两个距离差是我们来分析公式(2-10):(1)当此值为正时,d1>d2,说明直线上理论点离(x i+1,y i+1)象素较近,下一个象素点应取(x i+1,y i+1)。
(2)当此值为负时,d1<d2,说明直线上理论点离(x i+1,y i)象素较近,则下一个象素点应取(x i+1,y i)。
Bresenham算法

Course PagePage 1 of 6课程首页 > 第二章 二维图形的生成 > 2.1 直线的生成 > 2.1.2 生成直线的Bresenham算法全部隐藏2.1.2 生成直线的Bresenham算法从上面介绍的DDA算法可以看到,由于在循环中涉及实型数据的加减运算,因此直线的生成速度较慢。
在生成直线的算法中,Bresenham算法是最有效的算法之一。
Bresenham算法是一种基于误差判别式来生成直线的方法。
一、直线Bresenham算法描述: 它也是采用递推步进的办法,令每次最大变化方向的坐标步进一个象素,同时另一个方向的坐标依据误差判别式的符号来决定是否也要步进一 个象素。
我们首先讨论m=△ y/△x,当0≤m≤1且x1<x2时的Bresenham算法。
从DDA直线算法可知这些条件成立时,公式(2-2)、(2-3)可写成: xi+1=x i+1 yi+1=y i+m (2-6) (2-7)有两种Bresenham算法思想,它们各自从不同角度介绍了Bresenham算法思想,得出的误差判别式都是一样的。
二、直线Bresenham算法思想之一: 由于显示直线的象素点只能取整数值坐标,可以假设直线上第i个象素点坐标为(xi,yi),它是直线上点(xi,yi)的最佳近似,并且xi=xi(假设 m<1),如下图所示。
那么,直线上下一个象素点的可能位置是(xi+1,yi)或(xi+1,yi+1)。
由图中可以知道,在x=xi+1处,直线上点的y值是y=m(xi+1)+b,该点离象素点(xi+1,yi)和象素点(xi+1,yi+1)的距离分别是d1和d2:d1=y-yi=m(xi+1)+b-yi d2=(yi+1)-y=(yi+1)-m(xi+1)-b 这两个距离差是 d1-d2=2m(xi+1)-2yi+2b-1(2-8) (2-9)(2-10)我们来分析公式(2-10): (1)当此值为正时,d1>d2,说明直线上理论点离(xi+1,yi+1)象素较近,下一个象素点应取(xi+1,yi+1)。
正交连线算法

正交连线算法
正交连线算法是指在几何图形中,按照直角坐标系中的坐标轴方向进行连线的算法。
这种算法通常用于计算机图形学、CAD/CAM等领域中,用于生成直线、矩形、多边形等几何形状。
正交连线算法的基本思想是,按照坐标轴的方向,将起点和终点之间的线段划分为若干个小的线段段,并计算每个线段段的坐标值。
然后根据需要,可以使用不同的方法将这些线段连接起来,以形成所需的几何形状。
以下是一些正交连线算法的示例:
1.直线生成算法:给定起点和终点坐标,使用正交连线算法可以生成一条从
起点到终点的直线。
具体实现时,可以将直线划分为若干个小的线段段,并计算每个线段段的坐标值,最后将这些线段连接起来形成完整的直线。
2.矩形生成算法:给定矩形的一个角点坐标和其长宽尺寸,使用正交连线算
法可以生成一个矩形。
具体实现时,可以先生成两个对角线线段,然后分别计算矩形上边和下边、左边和右边的线段的坐标值,最后将这些线段连接起来形成完整的矩形。
3.多边形生成算法:给定多边形顶点的坐标和边长,使用正交连线算法可以
生成一个多边形。
具体实现时,可以先生成多边形的所有边线段,然后根据需要将这些边线段连接起来形成完整的多边形。
总的来说,正交连线算法是一种非常基础的几何算法,它可以用于生成各种几何形状,并且在计算机图形学、CAD/CAM等领域中有着广泛的应用。
随着计算机技术的发展,正交连线算法也在不断改进和完善,以适应更多的应用场景和需求。
直线和圆弧的生成算法

第3章直线和圆弧的生成算法3.1直线图形的生成算法数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。
当我们对直线进行光栅化时,需要在显示器有限个像素中,确定最佳逼近该直线的一组像素,并且按扫描线顺序,对这些像素进行写操作,这个过程称为用显示器绘制直线或直线的扫描转换。
由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。
本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法(DDA、中点画线法和Bresenham算法。
3.1.1逐点比较法3.1.2数值微分(DDA)法设过端点P o(x o , y°)、R(X1 , y1)的直线段为L( P0 , R),则直线段L的斜率为—沁生要在显示器显示厶必须确定最佳逼近Z的掃素集合。
我们从L的起点P0的横坐标X o向L的终点R的横坐标X1步进,取步长=1(个像素),用L 的直线方程y=kx+b计算相应的y坐标,并取像素点(x,round( y))作为当前点的坐标。
因为:y i+1 = kX i+1+b= k1X i +b+k x= y i+k x所以,当x =1; y i+1 = y i+k。
也就是说,当x每递增1,y递增k(即直线斜率)。
根据这个原理,我们可以写出DDA( Digital Differential Analyzer) 画线算法程序。
DDA画线算法程序: void DDALi ne(int xO,i nt yO,i nt x1,i nt y1,i nt color){ int x ;float dx, dy, y, k ;dx = x1-x0 ;dy=y1-y0 ;k=dy/dx, ;y=yO;for (x=xO ;x< x1 ;x++){ drawpixel (x, i nt(y+0.5), color);y=y+k;}}注意:我们这里用整型变量color表示像素的颜色和灰度。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为方便计算,令e=d-0.5,e的初值为-0.5, 增量为k。当e≥0时,取当前象素(xi,yi) 的右上方象素(xi+1,yi+1);而当e<0 时,更接近于右方象素(xi+1,yi)。
2012-3-31
29
Bresenham画线算法程序 void Bresenhamline (int x0,int y0,int x1, int y1,int color) { int x, y, dx, dy; float k, e; dx = x1-x0; dy = y1- y0; k=dy/dx; e=-0.5; x=x0; y=y0; for (i=0; i<=dx; i++) { Putpixel (x, y, color); x=x+1; e=e+k; if (e>= 0) { y++, e=e-1;} } }
取整: 取整: xi , yi )}in=0 {(
2012-3-31
{( xi , yi ,r )}in=0
8
yi ,r = round ( yi ) = (int)( yi + 0.5)
复杂度:乘法+加法 取整 复杂度:乘法 加法+取整 加法
DDA算法(增量算法) 算法(增量算法) 算法
= m • xi + B + m = yi + m
2012-3-31
12
改进算法(增量DDA)
增加斜率判断并改变循环参数
2012-3-31
13
DDA画线算法程序(改进)
void LineDDA(int x0,int y0,int x1,int y1,int color) { int x,y;float dx, dy,k,l,m; dx= float(x1-x0); dy= float(y1-y0); k=dy/dx; if abs(k)<1) { for(x=x0; x<= x1, x++) { Setpixel(x, int(y+0.5), color); y+=k; } } else { for(y=y0; y<= y1, y++) { Setpixel(int(x+0.5),y,color); x+=1/k; } } 问题: 如果x0> x1怎么办?
2012-3-31
x=x1; y=y1; k=1; while(k<=length) { SetPixel(hdc,x,y, RGB(0,0,0)); x=x+deltx; y=y+delty; k=k+1; Sleep(50); } }
16
画线中点算法
目标:消除 目标:消除DDA算法中的浮点运算(浮点数取整 算法中的浮点运算
运算,不利于硬件实现; DDA算法,效率低)
条件: 条件:
同DDA算法 算法 斜 率: m ∈ [ 0,1]
直线段的隐式方程( 直线段的隐式方程((x0,y0)(x1,y1)两端点) F(x,y)=ax+by+c=0 式中 a=y0-y1,b=x1-x0,c=X0Y1-X1Y0
2012-3-31
17
2012-3-31 14
DDA直线生成算法的伪语言描述如下: 直线生成算法的伪语言描述如下: 直线生成算法的伪语言描述如下 begin if abs(x2﹣x1)≥abs(y2﹣y1) ﹣ ﹣ then lenght﹦abs(x2﹣x1) ﹦ ﹣ else lenght﹦abs(y2﹣y1) ﹦ ﹣ endif △x﹦(x2﹣x1)/lenght ﹦ ﹣ △y﹦(y2﹣y1)/lenght ﹦ ﹣ x﹦ x﹦x1 y﹦y1 ﹦ k﹦1 ﹦ while(k≤lenght) putpixel(x,y) x﹦x﹢△x ﹦ ﹢ y﹦y﹢△y ﹦ ﹢ k﹦k﹢1 ﹦ ﹢ endwhile end
2012-3-31
6
描绘线条图形的要求
直线段要显得笔直 线段端点位置要准确 线段的亮度要均匀 转换算法速度要快
2012-3-31
7
DDA( digital differential analyzer)算法 ( 算法
条件: 条件:
待扫描转换的直线段: 待扫描转换的直线段:P0 ( x0, y 0) P ( x1, y1) 1 斜率: 斜率:m = ∆y / ∆x
2012-3-31 25
画线Bresenham算法 算法 画线
Bresenham算法是计算机图形学领域使用最广泛的直 线扫描转换算法。该方法类似于中点法,由误差项符 号决定下一个象素取右边点还是右上点。 本算法由Bresenham在1965年提出该方法最初是为数 字绘图仪设计的,后来被广泛地应用于光栅图形显示 和数控(NC)加工 算法原理如下:过各行各列象素中心构造一组虚拟网 格线。按直线从起点到终点的顺序计算直线与各垂直 网格线的交点,然后确定该列象素中与此交点最近的 象素。该算法的巧妙之处在于采用增量计算,使得对 于每一列,只要检查一个误差项的符号,就可以确定 该列的所求象素。
P2 P1 P
2012-3-31 22
d的初始值 d0=F(X0+1,Y0+0.5)=F(X0,Y0)+a+0.5*b 因 (X0,Y0) 在 直 线 上 , F(X0 , Y0)=0, 所 以 , d0=a+0.5*b d的增量都是整数,只有初始值包含小数,可以 用2d代替d, 2a改写成a+a。 算法中只有整数变量,不含乘除法,可用硬件 实现。
∆x = x1 − x0, ∆y = y1 − y 0 直线方程: 直线方程:y = m • x + B 直接求交算法: 直接求交算法: 划分区间[x0,x1]: x0 , x1 , L , xn , 其中xi +1 = xi + 1 划分区间 计算纵坐标: 计算纵坐标: yi = m • xi + B
2012-3-31
4
2 直线段的扫描转换
目标: 目标:求与直线段充分接近的像素集 像素间均匀网格 整型坐标系 两点假设
直线段的宽度为1 直线段的宽度为 直线段的斜率: 直线段的斜率
m ∈ [−1,1]
2012-3-31 5
基本图形点阵转换算法评价
所显示图形的精度 算法的时间和空间复杂性
两者冲突, 两者冲突,权衡折衷
2012-3-31
1
扫描转换直线段
• DDA算法 • 中点画线法 • Bresenham算法
圆弧、椭圆弧扫描转换
• 中点算法
• Bresenham算法 • 内接多边形迫近法* • 等面积多边形逼近法*
2012-3-31
2
1 简单的二维图形显示流程
2012-3-31
3
图形显示前需要:扫描转换+裁剪 ● 裁剪 ---〉扫描转换:最常用,节约计算时间。 ● 扫描转换 ---〉裁剪:算法简单; ● 扫描转换到画布 --〉位块拷贝:算法简单,但耗时耗 内存。常用于字符显示。
2012-3-31
18
直线的正负划分性
点与直线的关系:on: F(x,y)=0; up: F(x, y)>0; down: F(x, y)<0;
2012-3-31
19
欲判断中M在Q点的上方还是下方,只要把M代 F(x,y),并判断它的符号。 构造判别式: d=F(M)=F(xp+1, yp+0.5) =a(xp+1)+b(yp+0.5)+c 当d<0,M在Q点下方,取P2为下一个象素; 当d>0,M在Q点上方,取P1为下一个象素; 当d=0,选P1或P2均可,约定取P1为下一个象 素
2012-3-31
23
中点算法程序 MidPointLine(x0,y0,x1,y1,color) {int x0,y0,x1,y1,color; int a,b,d1,d2,x,y; a = y0-y1; b = x1 – x0; d = 2 * a +b; d1 = 2*a; d2 = 2*(a+b); x = x0; y = y0; SetPixel(x,y,color); while (x<x1) { if (d<0) { x++; y++; d +=d2;} else { x++; d +=d1;} SetPixel(x,y,color); } }
2012-3-31 24
举例 用中点画线方法扫描转换连接两点P0(0,0)和P1 (5,2)的直线段
a=y0-y1=-2; b=x1-x0=5; d0=2*a+b=1; d1=2*a=-4; d2=2*(a+b)=6 x y d 0 0 1 1 0 -3 d1 2 1 3 d2 3 1 -1 d1 4 2 5 d2 5 2 1
第二讲 二维基本图形生成
所谓图元的生成,是指完成图元的参数表示形式(由图 形软件包的使用者指定)到点阵表示形式(光栅显示系 统刷新时所需的表示形式)的转换。通常也称扫描转换 图元 §1 §2 §3 §4 §5 简单的二维图形显示流程 直线段的扫描转换 圆弧的扫描转换 易画曲线的正负法 线画图元的属性控制
2012-3-31
26
工作原理:根据直线的斜率在x或y的方向每次都 只递增一个象素单位,另一个方向的增量为0或1来自2012-3-3127
设直线方程为y=kx+b,其中k=dy/dx。 假 设x列的象素已经确定为xi,其行坐标为yi。 那么下一个象素的列坐标为xi+1,而行坐 标要么不变为yi,要么递增1为yi+1。 是否增1取决于如图所示误差项d的值。因为 直线的起始点在象素中心,所以误差项d的 初值d0=0。X下标每增加1,d的值相应递 d0 0 X 1 d 增直线的斜率值k,即d=d+k。 当d≥0.5时,直线与xi+1列垂直网格交点最 接近于当前象素(xi,yi)的右上方象素(xi +1,yi+1);而当d<0.5时,更接近于右 方象素(xi+1,yi)。