直线生成算法
- 格式:ppt
- 大小:387.00 KB
- 文档页数:69
实验二: 直线的生成算法的实现班级 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的直线生成算法时也是参考这篇博文。
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法的基本原理如下:
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算法。
生成直线的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)。
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表示像素的颜色和灰度。
基于Bresenham的任意宽度直线生成算法尹洪松;唐莉萍;曾培峰【摘要】直线生成算法是计算机图形的基本算法,而现有算法都有其弊端,因此提出一种基于Bresenham 任意宽度直线的生成算法。
该算法首先根据直线的斜率、长度和宽度计算出直线所形成的边界,然后让单线宽直线沿着边界移动,使整个区域填充。
该算法生成的直线两端与边界垂直,在直线斜率变化的情况下,直线宽度不会发生变化,且具有应用背景广泛、运算速度快、占用内存小等特点。
%The line generation algorithm is the basic graphics algorithm. And the existing algorithm have its drawbacks. So it is necessary to present an algorithm to generate a straight line of arbitrary width based on Bresenham. The algorithm firstly calculated line boundary according to the slope, length and width of lines, then uses single line with the same slope to fill the whole area. The ends of lines generated is vertical to the boundary line and its width does not change when its slope changes. This algorithm has extensive application background, fast operation speed, and small memory characteristics etc.【期刊名称】《微型机与应用》【年(卷),期】2015(000)016【总页数】4页(P24-26,29)【关键词】直线生成;Bresenham画线算法;区域填充【作者】尹洪松;唐莉萍;曾培峰【作者单位】东华大学信息科学与技术学院,上海 201620;东华大学信息科学与技术学院,上海 201620;东华大学计算机科学与技术学院,上海 201620【正文语种】中文【中图分类】TP311.1嵌入式图形系统的图形显示是通过光栅显示器来实现的,而光栅显示器实际上是一个像素矩阵,光栅显示器通过点亮一个个像素,确定最佳逼近于图像的像素集。
生成直线的dda算法
DDA算法是一种简单而有效的直线生成算法,可以使用数值计算来生成线段坐标。
本文将介绍DDA算法的实现原理、优缺点以及在实际应用中的使用情况。
一、DDA算法的实现原理:
DDA算法使用数值计算来计算每个像素的坐标,然后在屏幕上直接画出直线。
具体实现步骤如下:
1. 取两个端点(x1,y1)和(x2,y2)。
2. 计算dx,dy,m(斜率)和steps(使用的步骤)。
3. 计算xinc和yinc以确定绘制的方向。
4. 分配像素的坐标并在屏幕上绘制直线。
二、DDA算法的优缺点:
1. 优点:
(1)DDA算法能够生成直线。
(2)算法简单,易于实现。
(3)计算速度快,对硬件要求低。
2. 缺点:
(1)DDA算法产生的直线锯齿状。
(2)当线的斜率趋近于无穷大时,计算会出现分母无限大的错误,需要特殊处理。
(3)当线的斜率趋近于0时,计算会出现分母为0的错误,需要特殊处理。
三、DDA算法的应用:
DDA算法被广泛应用于计算机图形学中,常被用来生成直线和绘制几何图形。
例如,绘制线条、矩形、椭圆等形状,都会使用DDA算法。
此外,还有一些基于DDA算法的算法,如圆算法、填充算法等。
四、总结:
DDA算法是一种简单而有效的直线生成算法,具有计算速度快、对硬件要求低等优点。
然而,由于其产生的直线锯齿状,导致其在某些应用场景下难以满足要求。
在实际应用中,DDA算法被广泛应用于生成直线和绘制几何图形的场景中。