计算机图形学--Bresenham完整算法-画直线、椭圆和圆
中点bresenham算法过程
中点Bresenham算法是一种用于计算在直线上的格点的算法。
它是由Bresenham在1965年提出的,是一种高效的计算机图形学算法,通常用于直线、圆、椭圆等形状的绘制。
通过这篇文章,我们将详细介绍中点Bresenham算法的过程。
1. 背景知识在计算机图形学中,我们经常需要在屏幕上绘制直线、圆、椭圆等形状。
而计算机屏幕上的图像是由像素组成的,因此我们需要一种算法来计算出这些形状上的像素坐标,从而进行绘制。
中点Bresenham算法就是用来解决这个问题的。
2. 中点Bresenham算法的原理中点Bresenham算法的原理是通过巧妙的数学推导,找到离直线最近的像素点,从而确定需要绘制的像素坐标。
该算法通过利用误差项来判断下一个像素点的位置,具有高效、简洁的特点。
3. 中点Bresenham算法的过程中点Bresenham算法的过程可以分为以下几个步骤:3.1 初始化变量:首先需要确定直线的起点和终点,并初始化相关变量,如起点坐标(x0, y0)、终点坐标(x1, y1)、误差项d和增量变化量dx、dy等。
3.2 计算斜率k和误差项初始值:通过计算直线的斜率k,并根据斜率确定误差项的初始值。
3.3 循环计算像素点的坐标:根据误差项的大小,确定下一个像素点的位置,并更新误差项的值,直到绘制完整条直线。
4. 中点Bresenham算法的优势* 算法简洁高效:中点Bresenham算法通过简单的数学计算,即可确定直线上的像素坐标,避免了直接计算斜率导致的浮点数运算,因此在计算速度上具有较大优势。
* 适用范围广泛:中点Bresenham算法不仅适用于直线,还可以用于绘制圆、椭圆等图形,具有良好的通用性。
5. 中点Bresenham算法的应用中点Bresenham算法广泛应用于计算机图形学中的直线、圆、椭圆等图形的绘制。
其高效、简洁的特点使得它成为了计算机图形学中不可或缺的算法之一。
中点Bresenham算法是计算机图形学中的重要算法之一,通过巧妙的数学计算,实现了高效、简洁的直线绘制。
《图形学》实验四:中点Bresenham算法画直线
《图形学》实验四:中点Bresenham算法画直线VC++6.0,OpenGL使⽤中点Bresenham算法画直线。
1//中点Bresenham算法⽣成直线2 #include <gl/glut.h>3 #include <math.h>45#define WIDTH 500 //窗⼝宽度6#define HEIGHT 500 //窗⼝⾼度7#define DRAWLINE1 MidpointBresenham(100,200,200,100); //画直线8#define DRAWLINE2 MidpointBresenham(200,100,450,400); //画直线910#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //取消控制台1112void Init() //初始化13 {14 glClearColor(1.0f,1.0f,1.0f,1.0f); //设置背景颜⾊,完全不透明15 glColor3f(1.0f,0.0f,0.0f); //设置画笔颜⾊1617 glMatrixMode(GL_PROJECTION); //设置投影18 gluOrtho2D(0.0, WIDTH, 0.0, HEIGHT); //设置投影区域19 }2021void MidpointBresenham(int x0,int y0,int x1,int y1) //中点Bresenham算法画线22 {23int dx,dy,d,UpIncre,DownIncre,x,y;24if(x0>x1){25 x=x1;x1=x0;x0=x;26 y=y1;y1=y0;y0=y;27 }28 x = x0,y = y0;29 dx = x1-x0;30 dy = y1-y0;31if(dy>0&&dy<=dx){ //0<k<=132 d = dx-2*dy;33 UpIncre = 2*dx-2*dy;34 DownIncre = -2*dy;35while(x<=x1){36 glBegin(GL_POINTS);37 glVertex2i(x,y);38 glEnd();39 x++;40if(d<0){41 y++;42 d+=UpIncre;44else45 d+=DownIncre;46 }47 }48else if((dy>=(-dx))&&dy<=0) //-1<=k<=049 {50 d=dx-2*dy;51 UpIncre=-2*dy;52 DownIncre=-2*dx-2*dy;53while(x<=x1)54 {55 glBegin(GL_POINTS);56 glVertex2i(x,y);57 glEnd();58 x++;59if(d>0)60 {61 y--;62 d+=DownIncre;63 }64else d+=UpIncre;65 }66 }67else if(dy<(-dx)) //k<-168 {69 d=-dy-2*dx;70 UpIncre=2*dx+2*dy;71 DownIncre=2*dx;72while(y>=y1)73 {74 glBegin(GL_POINTS);75 glVertex2i(x,y);76 glEnd();77 y--;78if(d<0)79 {80 x++;81 d-=UpIncre;82 }83else d-=DownIncre;84 }85 }8687else//k>1和k不存在88 {89 d=dy-2*dx;90 UpIncre=2*dy-2*dx;91 DownIncre=-2*dx;92while(y<=y1)93 {94 glBegin(GL_POINTS);95 glVertex2i(x,y);96 glEnd();97 y++;98if(d<0)99 {100 x++;101 d+=UpIncre;103else d+=DownIncre;104 }105 }106 }107108void Display() //显⽰函数109 {110 glClear(GL_COLOR_BUFFER_BIT); //清空颜⾊堆栈111112 DRAWLINE1 //画直线113 DRAWLINE2 //画直线114115 glFlush(); //清空缓冲区指令116 }117118int main(int argc,char** argv)119 {120 glutInit(&argc,argv);121 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); //初始化显⽰模式122 glutInitWindowSize(WIDTH,HEIGHT); //设置窗⼝尺⼨123 glutInitWindowPosition(200,100); //设置窗⼝位置124 glutCreateWindow("画直线"); //创建窗⼝125126 glutDisplayFunc(Display); //注册显⽰函数127 Init(); //初始化128 glutMainLoop(); //进⼊程序循环129return0;130 }Freecode :。
计算机图形学-三种直线生成算法及圆的生成算法
计算机科学与技术学院2013-2014学年第一学期《计算机图形学》实验报告班级:110341C学号:110341328姓名:田野教师:惠康华成绩:实验(一):平面图形直线和圆的生成一、实验目的与要求1.在掌握直线和圆的理论基础上,分析和掌握DDA生成直线算法、中点生成直线算法、Bresenham生成直线算法、中点画圆算法、Bresenham圆生成算法。
2.熟悉VC6.0MFC环境,利用C语言编程实现直线和圆的生成。
3.比较直线生成三种算法的异同,明确其优点和不足。
同时了解圆的生成算法适用范围。
二、实验内容1.掌握VC6.0环境中类向导和消息映射函数的概念,并且为本次实验做好编程准备工作。
2. 用C语言进行编程实现上述算法,并且调试顺利通过。
3. 在MFC图形界面中显示不同算法下的图形,并且注意对临界值、特殊值的检验。
完成后保存相关图形。
三、算法分析➢DDA直线生成算法描述:1)给定一直线起始点(x0,y0)和终点(x1,y1)。
分别计算dx=x1-x0,dy=y1-y0。
2)计算直线的斜率k=dy/dx。
当|k|<1时转向3);当|k|<=1时,转向4);3)当x每次增加1时,y增加k。
即(xi,yi)→(xi+1,yi+k)。
直到xi增加到x1。
并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对y坐标要进行int(y+0.5)取整运算。
结束。
4)对y每次增加1时,x增加1/k,即(xi,yi)→(xi+1/k,yi+1)。
直到yi增加到y1. 并且每次把得到的坐标值利用系统函数扫描显示出来。
但要注意对x坐标要进行int(x+0.5)取整运算。
结束。
➢中点生成算法描述:算法基本思想:取当前点(xp,yp),那么直线下一点的可能取值只能近的正右方点P1(xp+1,yp)或者P2(xp+1,yp+1)。
为了确定好下一点,引入了这两点中的中点M(xp+1,yp+0.5)。
这时可以把改点带入所在直线方程,可以观察该中点与直线的位置关系。
直线、圆、椭圆的生成算法
计算机科学与技术学院2012-2013学年第一学期《计算机图形学》实验报告班级:100341C学号:100341328姓名:魏然教师:惠康华成绩:实验项目:直线、圆、椭圆的生成算法一、实验目的与要求(1)了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在实验设计集成环境(IDE)下进行图形处理程序的设计方法。
(2)熟练掌握直线的3种扫描转换算法:DDA算法,中点算法和Bresenham算法。
(3)掌握中点画圆算法、圆的Brensenham算法和椭圆的中点算法。
二、实验内容(1)在Visual C++环境中设计MFC单文档程序,利用消息处理函数,搭建能运行图形算法程序的平台。
(2)在平台中使用已有的点、线、圆等绘图函数,设计一个平面图形。
Visual C++基本绘图函数可参考有关文献。
(3)根据教材中给定的算法,实现直线段的3种生成算法:DDA算法,中点法和Bresenham算法。
(4)根据教材中给定的算法,实现圆与椭圆的生成算法。
三、重要算法分析(一)、直线的生成1、DDA算法定义直线两端点和直线颜色:整型变量 x0=?, y0=?,x1=?,y1=?,c=颜色;定义整型变量x,y,i;浮点数dx,dy,k;根据数学算法得到斜率k,k=dy/dx,其中dx=(float)(x1-x0),dy=(float)(y1-y0);定义x=x0;y=y0;通过对x和y各增加一个小增量,计算下一步的x、y值。
当k的绝对值小于1的时候,标记一个像素点,像素点的坐标为(x,int(y+0.5),c),y=y+k,如果x=x i,则停止;当k的绝对值大于或等于1的时候,标记一个像素点,像素点的坐标为(int(x+0.5),y,c),x=x+1/k,如果y=y i,则停止;2、中点算法定义直线两端点和直线颜色:整型变量 x0=?, y0=?,x1=?,y1=?,c=颜色;定义浮点数:a,b,d1,d2,d,x,y;假设直线方程f(x,y)=ax+by+c=0,则a=y0-y1;b=x1-x0;判别式d=2*a+b;d1=2*a;d2=2*(a+b);定义x=x0;y=y0;标记像素点(x,y,c);x值逐一增加,y值取决于d;当d大于等于0的时候,取正右方的点,上一步的d值加d1;当d小于0的时候,取右上方的点,上一步的d值加d2;3、Bresenham算法定义直线两端点和直线颜色:整型变量 x0=?, y0=?,x1=?,y1=?,c=颜色;定义整型变量 i,x,y,dx,dy;整型变量:k,e;dx=x1-x0,dy=y1-y0;e=-dx;定义x=x0;y=y0;标记像素点(x,y,c),x逐一增加,e=e+2*dy,其中如果e>=0,则y增加,e=e-2*dx, 如果x=x i,则停止;(二)、圆的生成1、中点画圆定义圆的中点和圆弧颜色:整型变量 x0=?, y0=?,r=?,c=颜色,x,y,d;使x=0,y=r,d=1-r;标记像素点(x,y,c);当x<=y的时候,如果d<0,则d=d+2*x+3;否则d=d+2*(x-y)+5,y逐一减;x逐一增加,标记像素点(x+x0,y+y0,c);标记像素点(-x+x0,y+y0,c);标记像素点(-x+x0,-y+y0,c);标记像素点(x+x0,-y+y0,c);标记像素点(y+x0,x+y0,c);标记像素点(-y+x0,x+y0,c);标记像素点(-y+x0,-x+y0,c);标记像素点(y+x0,-x+y0,c);2、Bresenham画圆定义圆的中点和圆弧颜色:整型变量 x0=?, y0=?,r=?,c=颜色,x,y,e;浮点数e,d;使x=0,y=r,e=3-2*r;当x<=y的时候,如果e<0,则e=e+4*x+6,x逐一增加;否则e=e+4*(x-y)+10,x逐一增加,y逐一减;标记像素点(x+x0,y+y0,c);标记像素点(-x+x0,y+y0,c);标记像素点(-x+x0,-y+y0,c);标记像素点(x+x0,-y+y0,c);标记像素点(y+x0,x+y0,c);标记像素点(-y+x0,x+y0,c);标记像素点(-y+x0,-x+y0,c);标记像素点(y+x0,-x+y0,c);四、程序运行截图图1 直线的生成图2 圆的生成五、总结与调试经验通过本次试验,我初步了解了怎样在计算机上进行图形处理,并且学会了怎样在Visual C++上创建生成图形的工程,用不同算法实现了直线和圆的生成,知道了各个算法之间的优缺点。
布兰森汉姆(Bresenham)算法画线
int s1,s2,status,i; int Dx,Dy,sub;
dx=x1-x0; if(dx>=0) s1=1; else s1=-1; dy=y1-y0; if(dy>=0) s2=1; else s2=-1; //判断Y的方向是增加还是降到的 //X的方向是降低的 //X的方向是增加的
( Word Converter - 未滨册 ) http://www.
( Word Converter - 未滨册 ) http://www.
} }
这是在以(63,32)为圆心,32为半径画的圆(帏问题是当圆大后,会有部分画不出来,有待完善)
4、整幏画图部分 这个比较简单,帱直接上程序了 void LCD_fulldisplay_picture_2(const uchar *pic) //全幏显示图片方滕2 { unsigned int x=0; unsigned char i,j; Write_command(0x34); Write_command(0x36); for(i=0;i<32;i++) { Write_command(0x80|i); Write_command(0x80); //列位置 //行位置 //扩幕指令动作 //扩幕指令动作 //上半幏显示
st7920控制的 12864液晶画线,画圆,作图
1、打点部分 该部分已在该论坛发帖,这里不帱重复了 (打点是所有绘图的基础) 2、画线部分 先看程序 /******************************************************** * 名称:GUI_Line() 采用布兰森湉姆(Bresenham)算滕画线 * 功能:任意两点间的直线。根据硬件特点,实现加速。 * 入口参数:x0 * * ‘ y0 x1 y1 直线起点所在行的位置
bresenham算法画直线例题
Bresenham算法是计算机图形学中常用的一种画直线的算法。
它的原理是利用像素点在屏幕上的排列规律,从而高效地计算出直线上的像素点。
本文将以一个具体的例题来说明Bresenham算法的原理及应用。
1. 问题描述假设我们需要在一个分辨率为800x600的屏幕上,画一条直线,起点坐标为(100, 200),终点坐标为(400, 300)。
请使用Bresenham算法计算直线上的像素点,并用符号“*”表示出来。
2. Bresenham算法原理Bresenham算法的核心思想是利用像素点的整数坐标值与直线的斜率之间的关系,从而逐个确定直线上的像素点。
具体步骤如下:- 计算直线的斜率k,即k = (y2 - y1) / (x2 - x1),其中(x1, y1)为起点坐标,(x2, y2)为终点坐标。
- 以起点坐标作为初始值,从左至右依次求解直线上各点像素的坐标。
- 对于每一个x坐标,根据斜率k的大小确定y坐标的增长方向。
3. Bresenham算法应用根据上述原理,我们来解决具体的例题。
计算直线的斜率k:k = (300 - 200) / (400 - 100) = 1/3以起点坐标(100, 200)作为初始值,从左至右依次求解直线上各点像素的坐标。
当x坐标从100递增至400时,y坐标的增长方向由斜率k来确定。
具体计算如下:- 当x=100时,y=200- 当x=101时,y=200+1/3≈200- 当x=102时,y=200+2/3≈201- ...- 当x=400时,y=300现在,我们可以得到直线上的像素点坐标,并用符号“*”表示出来。
4. 结果展示根据上述计算,我们可以得到该直线上的像素点坐标,展示如下:(100, 200) *(101, 200) *(102, 201) *...(400, 300) *通过Bresenham算法,我们成功地计算出了直线上的像素点,并用符号“*”进行了展示。
bresenham算法例题详解
让我们回顾一下Bresenham算法的基本原理。
Bresenham算法是一种用于绘制直线、圆和椭圆的算法,它最初是由Jack Elton Bresenham在1962年提出的。
这个算法的核心思想是利用整数运算来高效地计算出图形上的点,从而避免使用浮点运算,提高了绘制图形的速度。
接下来,我们来看一个简单的例题,以便更好地理解Bresenham算法的具体应用。
假设我们需要在一个像素点阵上绘制一条直线,起点坐标为(2, 3),终点坐标为(8, 5)。
我们可以利用Bresenham算法来计算出直线上的所有像素点,具体步骤如下:1. 计算直线斜率k:k = (终点y坐标 - 起点y坐标) / (终点x坐标 - 起点x坐标)2. 初始化误差项:误差项e = 03. 从起点开始,依次计算直线上的像素点:- 如果斜率k < 1,选择沿x轴方向的像素点,即x轴加1,y轴不变- 如果斜率k > 1,选择沿y轴方向的像素点,即x轴不变,y轴加1- 更新误差项e:e = e + |k|通过以上步骤,我们可以依次计算出直线上的像素点,并用Bresenham算法高效地绘制直线。
在这个例题中,我们可以看到Bresenham算法的简单实现步骤,它不仅可以用于绘制直线,还可以应用于绘制圆和椭圆。
这种基于整数运算的高效算法在图形学和计算机图形学中有着广泛的应用。
通过对Bresenham算法的例题详解,我们对这个算法的原理和应用有了更深入的理解。
Bresenham算法的高效性和简单性使得它成为了计算机图形学中不可或缺的重要算法,而且它的应用也不仅限于直线的绘制,还可以拓展到更多的图形绘制领域。
希望通过这个例题的解析,你对Bresenham算法有了更清晰的认识。
Bresenham算法的应用不仅限于直线的绘制,它还可以被推广应用到其他图形绘制的领域,比如圆和椭圆的绘制。
在这些领域,Bresenham算法同样能够高效地计算出图形上的像素点,从而实现快速绘制图形的效果。
计算机图形学-直线、圆、椭圆的生成
2014-9-5
中点画线法
假设直线方程为:ax+by+c=0 其中a=y0-y1, b=x1-x0, c=x0y1-x1y0 由常识知:
F x, y 0 F x, y 0 F x, y 0 点在直线上面 点在直线上方 点在直线下方
P2
Q
P=(xp,yp) P1
2014-9-5 浙江大学计算机图形学 28
圆的扫描转换
圆的扫描转换是在屏幕像素点阵中确定最佳逼近于 理想圆的像素点集的过程。圆的绘制可以使用简单方程 画圆算法或极坐标画圆算法,但这些算法涉及开方运算 或三角运算,效率很低。主要讲解仅包含加减运算的顺 时针绘制 1/8 圆的中点 Bresenham 算法原理,根据对称 性可以绘制整圆 。
2014-9-5 浙江大学计算机图形学 22
设图中xi列上已用(xi,yir)作为表示直线的点, 又设B点是直线上的点,其坐标为(xi+1,yi+1),显然 下一个表示直线的点( xi+1,yi+1,r)只能从图中的C 或者D点中去选。设A为CD边的中点。 若B在A点上面 则应取D点作为( xi+1,yi+1,r),否则应取C点。
P=(xp,yp ) P1 浙江大学计算机图形学
16
中点画线法
若d<0->M在直线下方->取P2; 此时再下一个象素的判别式为 d2= F(xp+2, yp+1.5) =a(xp+2)+b(yp+1.5)+c = a(xp +1)+b(yp +0.5)+c +a +b =d+a+b ; 增量为a+b
Bresenham画线画圆算法
Bresenham画线算法以前看到Bresenham画线算法,直接拿来用,没有去推导它,近日,参考一些资料,特整理其算法推导过程如下。
各位大虾如果知道其细节,赶紧闪过,不用浪费时间了。
基本上Bresenham画线算法的思路如下:// 假设该线段位于第一象限内且斜率大于0小于1,设起点为(x1,y1),终点为(x2,y2).// 根据对称性,可推导至全象限内的线段.1.画起点(x1,y1).2.准备画下个点。
x坐标增1,判断如果达到终点,则完成。
否则,由图中可知,下个要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点.2.1.如果线段ax+by+c=0与x=x1+1的交点的y坐标大于M点的y坐标的话,下个点为U(x1+1,y1+1)2.2.否则,下个点为B(x1+1,y1)3.画点(U或者B).4.跳回第2步.5.结束.这里需要细化的是怎么判断下个要画的点为当前点的右邻接点还是当前点的右上邻接点.设线段方程:ax+by+c=0(x1<x<x2,y1<y<y2)令dx=x2-x1,dy=y2-y1则:斜率-a/b = dy/dx.从第一个点开始,我们有F(x,1,y1) = a*x1+b*y1+c=0下面求线段ax+by+c=0与x=x1+1的交点:由a*(x1+1)+b*y+c = 0, 求出交点坐标y=(-c-a(x1+1))/b所以交点与M的y坐标差值Sub1 = (-c-a(x1+1))/b - (y1+0.5) = -a/b-0.5,即Sub1的处始值为-a/b-0.5。
则可得条件当 Sub1 = -a/b-0.5>0时候,即下个点为U.反之,下个点为B.代入a/b,则Sub1 = dy/dx-0.5.因为是个循环中都要判断Sub,所以得求出循环下的Sub表达式,我们可以求出Sub的差值的表达式.下面求x=x1+2时的Sub,即Sub21.如果下下个点是下个点的右上邻接点,则Sub2 = (-c-a(x1+2))/b - (y1+1.5) = -2a/b - 1.5故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 1.5 - (-a/b-0.5) = -a/b - 1.代入a/b得Dsub = dy/dx -1;2.如果下下个点是下个点的右邻接点,Sub2 = (-c-a(x1+2))/b - (y1+0.5) = -2a/b - 0.5故Sub差值Dsub = Sub2 - Sub1 = -2a/b - 0.5 - (-a/b-0.5) = -a/b. 代入a/b得Dsub = dy/dx;于是,我们有了Sub的处始值Sub1 = -a/b-0.5 = dy/dx-0.5,又有了Sub的差值的表达式Dsub = dy/dx -1 (当Sub1 > 0)或 dy/dx(当Sub1 < 0).细化工作完成。
计算机图形学课程设计报告--直线和圆中点Bresenham算法
计算机图形学课程设计报告课题名称直线和圆中点Bresenham算法1、课程设计目的 (2)2、课程设计描述及要求 (2)3、系统开发环境 (2)4、直线的Bresenham算法原理 (2)4.1中点Bresenham算法 (2)4.2该进的Bresenham算法 (5)5、圆的Bresenham算法原理 (7)6、程序运行结果 (9)7、总结 (11)8、参考资料 (11)9、附录 (11)计算机图形学课程设计报告1.课程设计目的本学期系统学习了计算机图形学的概论原理,在学期期末按课程要求进行实验。
通过实验,进一步理解和掌握中点算法、Bresenham 算法和二阶差分算法, 并掌握以上算法生成圆和直线等图形的基本过程,提高学生对计算机图形学的了解与运用技巧,同时通过此次课程设计提高动手实践能力与学习分析能力。
2.课程设计描述及要求 ●直线中点Bresenham 算法掌握中点Bresenham 算法绘制直线的原理,设计中点Bresenham 算法,编写Mbline()子函数,使用中点Bresenham 算法绘制斜率为0≦k ≦1的直线 ●圆中点Bresenham 算法掌握八分法中点Bresenham 算法绘制圆的原理,设计八分法绘制圆的中点Bresenham 算法,编写八分法绘制圆的CirclePoint(x,y)子函数,编写绘制整圆的Mbcircle()子函数,使用中点Bresenham 算法绘制圆心位于屏幕客户区中心的圆。
此次课程设计的课题为通过编程,实现圆和直线等基本图形的绘制。
要求用Bresenham 算法实现圆和直线等基本图形的绘制,并给出代码和结果截图。
3.系统开发环境 开发工具:VC 6.0操作系统:Microsoft Windows XP 4. 直线的Bresenham 算法原理 4.1中点Bresenham 算法给定直线的两个端点00111P X Y P X Y (,)和(,),可得到直线方程F(x,y)=y-kx-b=0且这时直线将平面分为三个区域:对于直线上的点,F(x,y)=0;对于直线上方的点,F(x,y)>0;对于直线下方的点,F(x,y)<0。
画圆形(Bresenham算法)
画圆形(Bresenham算法)下⾯先简要介绍常⽤的画圆算法(Bresenham算法),然后再具体阐述笔者对该算法的改进。
⼀个圆,如果画出了圆上的某⼀点,那么可以利⽤对称性计算余下的七段圆弧:Plot(x,y),Plot(y,x),Plot(y,-x),Plot(x,-y),Plot(-x,-y),Plot(-y,-x),Plot(-y,x),Plot(-x,y)。
1、Bresenham 画圆算法。
Bresenham算法的主要思想是:以坐标原点(0,0)为圆⼼的圆可以通过0度到45°的弧计算得到,即x从0增加到半径,然后利⽤对称性计算余下的七段圆弧。
当x从0增加到时,y从R递减到。
设圆的半径为R,则圆的⽅程为:f(x,y)=(x+1)2+y2-R2=0 (1)假设当前列(x=xi列)中最接近圆弧的像素已经取为P(xi,yi),根据第⼆卦限1/8圆的⾛向,下⼀列(x=xi+1列)中最接近圆弧的像素只能在P的正右⽅点H(xi+1,yi)或右下⽅点L(xi+1,yi-1)中选择,如图1所⽰。
Bresenham画圆算法采⽤点T(x,y)到圆⼼的距离平⽅与半径平⽅之差D(T)作为选择标准,即D(T)=(x+1)2+y2-R2 (2)通过⽐较H、L两点各⾃对实圆弧上点的距离⼤⼩,即根据误差⼤⼩来选取,具有最⼩误差的点为绘制点。
根据公式(2)得:对H(xi+1,yi)点有:D(H)=(xi+1)2+yi2-R2;对L(xi+1,yi-1)点有:D(L)=(xi+1)2+(yi-1)2-R2;根据Bresenham画圆算法,则选择的标准是:如果|D(H)|<|D(L)|,那么下⼀点选取H(xi+1,yi);如果|D(H)|>|D(L)|,那么下⼀点选取L(xi+1,yi-1);如果|D(H)|=|D(L)|,那么下⼀点可以取L(xi+1,yi-1),也可以选取H(xi+1,yi),我们约定选取H(xi+1,yi)。
计算机图形学--Bresenham完整算法-画直线、椭圆和圆
#include<windows.h>#include<gl/glut.h>#include"stdio.h"int m_PointNumber = 0; //动画时绘制点的数目int m_DrawMode = 1; //绘制模式 1 DDA算法画直线// 2 中点Bresenham算法画直线// 3 改进Bresenham算法画直线// 4 八分法绘制圆// 5 四分法绘制椭圆//绘制坐标线void DrawCordinateLine(void){int i = -250 ;//坐标线为黑色glColor3f(0.0f, 0.0f ,0.0f);glBegin(GL_LINES);for (i=-250;i<=250;i=i+10){glVertex2f((float)(i), -250.0f);glVertex2f((float)(i), 250.0f);glVertex2f(-250.0f, (float)(i));glVertex2f(250.0f, (float)(i));}glEnd();}//绘制一个点,这里用一个正方形表示一个点void putpixel(GLsizei x, GLsizei y){glRectf(10*x,10*y,10*x+10,10*y+10);}/////////////////////////////////////////////////////////////////////DDA画线算法 //// //// //// /////////////////////////////////////////////////////////////////////void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {//设置颜色glColor3f(1.0f,0.0f,0.0f);//对画线动画进行控制if(num == 1)printf("DDA画线算法:各点坐标\n");else if(num==0)return;//画线算法的实现GLsizei dx,dy,epsl,k;GLfloat x,y,xIncre,yIncre;dx = x1-x0;dy = y1-y0;x = x0;y = y0;if(abs(dx) > abs(dy)) epsl = abs(dx);else epsl = abs(dy);xIncre = (float)dx / epsl ;yIncre = (float)dy / epsl ;for(k = 0; k<=epsl; k++){putpixel((int)(x+0.5), (int)(y+0.5));if (k>=num-1) {printf("x=%f , y=%f,取整后 x=%d,y=%d\n", x, y, (int)(x+0.5),(int)(y+0.5));break;}x += xIncre;y += yIncre;if(x >= 25 || y >= 25) break;}}/////////////////////////////////////////////////////////////////////中点Bresenham算法画直线(0<=k<=1) //// //// //// /////////////////////////////////////////////////////////////////////void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num == 1)printf("中点Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;GLfloat UpIncre,DownIncre,x,y,d,k,dx,dy;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}x=x0;y=y0;dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){d=dx-2*dy;UpIncre=2*dx-2*dy;DownIncre=-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d<0){y++;d+=UpIncre;}else d+=DownIncre;}}if(k>1){d=dy-2*dx;UpIncre=2*dy-2*dx;DownIncre=-2*dx;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}if(k<0&&k>=-1){d=dx-2*dy;UpIncre=-2*dy;DownIncre=-2*dx-2*dy;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;if(d>0){y--;d+=DownIncre;}else d+=UpIncre;}}if(k<-1){d=-dy-2*dx;UpIncre=-2*dx-2*dy;DownIncre=-2*dx;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;if(d<0){x++;d+=UpIncre;}else d+=DownIncre;}}}/////////////////////////////////////////////////////////////////////改进的Bresenham算法画直线(0<=k<=1) //// //// x1,y1 终点坐标 //// /////////////////////////////////////////////////////////////////////void Bresenham2Line(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei x,y,dx,dy,e,k;if(num == 1)printf("改进的Bresenham算法画直线各点坐标及判别式的值\n");else if(num==0)return;//画线算法的实现GLsizei p=0;if(x0>x1){x=x1;x1=x0;x0=x;y=y1;y1=y0;y0=y;}dx=x1-x0;dy=y1-y0;k=dy/dx;if(k>=0&&k<=1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e>0){y++;e=e-2*dx;}}}if(k>1){e=-dy;x=x0;y=y0;while(y<=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y++;e=e+2*dx;if(e>0){x++;e=e-2*dy;}}}if(k<0&&k>=-1){e=-dx;x=x0;y=y0;while(x<=x1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;x++;e=e+2*dy;if(e<0){y--;e=e+2*dx;}}}if(k<-1){e=-dy;x=x0;y=y0;while(y>=y1){putpixel(x,y);if (p>=num-1) {printf("x=%d,y=%d\n", x, y);break;}p++;y--;e=e-2*dx;if(e<0){x++;e=e-2*dy;}}}}///////////////////////////////////////////////////////////Bresenham算法画圆 //// //// //// ///////////////////////////////////////////////////////////void CirclePoint(GLsizei x,GLsizei y){ putpixel(x,y);putpixel(x,-y);putpixel(y,-x);putpixel(-y,-x);putpixel(-x,-y);putpixel(-x,y);putpixel(-y,x);putpixel(y,x);}void BresenhamCircle(GLsizei x, GLsizei y, GLsizei R, GLsizei num) {glColor3f(1.0f,0.0f,0.0f);GLsizei d;x=0;y=R;d=1-R;if(num == 1)printf("Bresenham算法画圆:各点坐标及判别式的值\n");else if(num==0)return;while(x<=y){CirclePoint(x,y);if (x>=num-1) {printf("x=%d,y=%d,d=%d\n", x, y,d);break;}if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}x++;}}void Bresenham2Circle(GLsizei a,GLsizei b,GLsizei num){glColor3f(1.0f,0.0f,0.0f);if(num==1)printf("Bresenham算法画椭圆:各点坐标及判别式的值\n");else if(num==0)return;GLsizei x,y;float d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.5);putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);while(b*b*(x+1)<a*a*(y-0.5)){if (x>=num-1) {printf("x=%d,y=%d,d1=%d\n", x, y,d1);break;}if(d1<=0){d1+=b*b*(2*x+3);x++;}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);x++;y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}//while上半部分d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while(y>0){if (x>=num-1) {printf("x=%d,y=%d,d2=%d\n", x, y,d2);break;}if(d2<=0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;y--;}else{d2+=a*a*(-2*y+3);y--;}putpixel(x,y); putpixel(-x,-y);putpixel(-x,y);putpixel(x,-y);}}//初始化窗口void Initial(void){// 设置窗口颜色为蓝色glClearColor(0.0f, 0.0f, 1.0f, 1.0f);}// 窗口大小改变时调用的登记函数void ChangeSize(GLsizei w, GLsizei h){if(h == 0) h = 1;// 设置视区尺寸glViewport(0,0, w, h);// 重置坐标系统glMatrixMode(GL_PROJECTION);glLoadIdentity();// 建立修剪空间的范围if (w <= h)glOrtho (-250.0f, 250.0f, -250.0f, 250.0f*h/w, 1.0, -1.0);elseglOrtho (-250.0f, 250.0f*w/h, -250.0f, 250.0f, 1.0, -1.0);}// 在窗口中绘制图形void ReDraw(void){//用当前背景色填充窗口glClear(GL_COLOR_BUFFER_BIT);//画出坐标线DrawCordinateLine();switch(m_DrawMode){case 1:DDACreateLine(0,0,20,15,m_PointNumber);break;case 2:BresenhamLine(0,0,-20,15,m_PointNumber);break;case 3:Bresenham2Line(1,1,8,6,m_PointNumber);break;case 4:BresenhamCircle(0,0,20,m_PointNumber);break;case 5:Bresenham2Circle(10,8,m_PointNumber);default:break;}glFlush();}//设置时间回调函数void TimerFunc(int value){if(m_PointNumber == 0)value = 1;m_PointNumber = value;glutPostRedisplay();glutTimerFunc(500, TimerFunc, value+1);}//设置键盘回调函数void Keyboard(unsigned char key, int x, int y) {if (key == '1') m_DrawMode = 1;if (key == '2') m_DrawMode = 2;if (key == '3') m_DrawMode = 3;if (key == '4') m_DrawMode = 4;if (key == '5') m_DrawMode = 5;m_PointNumber = 0;glutPostRedisplay();}//void main(void)int main(int argc, char* argv[]){glutInit(&argc, argv);//初始化GLUT库OpenGL窗口的显示模式glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(600,600);glutInitWindowPosition(100,100);glutCreateWindow("基本图元绘制程序);glutDisplayFunc(ReDraw);glutReshapeFunc(ChangeSize);glutKeyboardFunc(Keyboard);//键盘响应回调函数glutTimerFunc(500, TimerFunc, 1);// 窗口初始化Initial();glutMainLoop(); //启动事件处理循环return 0;}。
计算机图形学-画椭圆和圆
}
x++;
glVertex2i(x +xc, y +yc);
glVertex2i(y +xc, x +yc);
glVertex2i(y +xc, -x +yc);
glVertex2i(x +xc, -y +yc);
glVertex2i(-x +xc, -y +yc);
glVertex2i(-y +xc, -x +yc);
绘图过程如下:
.输入直线的两端点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更新为△y。
.当直线没有画完时,重复步骤 ,否则结束。
intx = 0;
inty =b;
Ellipsepot(x0,y0, x, y);
// 1
while(sqb*(x + 1) < sqa*(y - 0.5))
{
if(d < 0)
{
d += sqb*(2 * x + 3);
}
else
{
d += (sqb*(2 * x + 3) + sqa*((-2)*y + 2));
glVertex2i(198,2);
glEnd();
glFlush(); //清空OpenGL命令缓冲区,执行OpenGL程序
Bresenham算法
void DDALine(int x0,int y0,int x1,int y1,int color) int i; float dx, dy, length,x,y; 举例: 线段P0(0,0)和P1(5,2)的DDA方法扫描转换。 if (fabs(x1-x0)>=fabs(y1-y0)) Line: P0(0, 0)-- P1(5, 2) length=fabs(x1-x0); x int(y+0.5) y+0.5 0 0 0+0.5 3 else 0.4+0.5 length=fabs(y1-y0); 1 0 2 2 1 0.8+0.5 dx = (x1-x0)/length; 3 1 1.2+0.5 1 dy=(y1-y0)/length; 4 2 1.6+0.5 i=1;x= x0;y= y0; 5 2 2.0+0.5 0 1 2 3 4 5 while(i<=length) { 图3-2 直线段的DDA扫描转换 SetPixel (int(x+0.5), int(y+0.5), color); x=x+dx; y=y+dy; i++; DDA算法与基本算法相比,减少了浮点乘法,提高了效率。但是x 与dx、y与dy用浮点数表示,每一步要进行四舍五入后取整,不利于硬 件实现,因而效率仍有待提高。
hi x(d1 d 2 )
则hi的计算仅包括整数运算,其符号与(d1-d2)的符号相同。 当hi<0时,直线上理想位置与像素(xi+1,yi)更接近,应取右方像素; 当hi>0时,像素(xi+1,yi+1)与直线上理想位置更接近; 当 hi=0 时,两个像素与直线上理想位置一样接近,可约定取(xi + 1 ,yi + 1)。
华科大图形学报告 中点Bresenham 算法 画直线 画圆 线刷子 日地月模型 光照模型
计算机图形学上机实验报告计算机科学与技术学院班级: 0 9 1 1 班学号: U200915XXX姓名: XXXX指导教师:徐海银完成日期: 2011/12/06目录实验一实验目的与要求------------------------------------1实验内容与分析------------------------------------1实验结果显示---------------------------------------3实验体会---------------------------------------------8源代码------------------------------------------------8实验二实验目的与要求------------------------------------18实验内容与分析------------------------------------18实验结果显示---------------------------------------19实验体会---------------------------------------------19源代码-----------------------------------------------20实验一(基本图元绘制)实验目的与要求(1)理解glut程序框架; (2)理解窗口到视区的变换 ;(3)理解OpenGL实现动画的原理; (4)添加代码实现中点Bresenham算法画直线;(5)添加代码实现改进Bresenham算法画直线;(6)添加代码实现圆的绘制(可以适当对框架坐标系进行修改);(7)适当修改代码实现具有宽度的图形(线刷子或方刷子)。
实验内容与分析①中点Bresenham 算法画直线思想:仅考虑0≤k≤1,由于最大位移方向为x,因此,每次x方向上加1,而y方向上或加1或加0。
计算机图形学-画椭圆和圆
glEnd();
glFlush(); //清空OpenGL命令缓冲区,执行OpenGL程序
}
int main(int argc,char*argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); //初始化窗口的显示模式
// 1
while(sqb*(x + 1) < sqa*(y {
d += sqb*(2 * x + 3);
}
else
{
d += (sqb*(2 * x + 3) + sqa*((-2)*y + 2));
--y;
}
++x;
Ellipsepot(x0,y0, x, y);
// glRectf(50.0f,100.0f,150.0f,50.0f); //绘制一个矩形
glPointSize(10); //三个点
glBegin(GL_POINTS);
glColor3f(1.0f,0.0f,0.0f);
glVertex2i(2,148);
glVertex2i(100,75);
实验一
1.实验目的
了解OpenGL编程,并熟悉OpenGL的主要功能、绘制流程和基本语法。学会配置OpenGL环境,并在该环境中编程绘图。
2.实验内容
OpenGL的主要功能:模型绘制、模型观察、颜色模式、光照应用、图像效果增强、位图和图像处理、纹理映射、实时动画和交互技术。
OpenGL的绘制流程分为两个方面:一个完整的窗口系统的OpenGL图形处理系统的结构为:最底层为图形硬件,第二层为操作系统,第三层为窗口系统,第四层为OpenGL,最上面的层为应用软件;OpenGL命令将被放在一个命令缓冲区中,这样命令缓冲区中包含了大量的命令、顶点数据和纹理数据。当缓冲区被清空时,缓冲区中的命令和数据都将传递给流水线的下一个阶段。
Bresenham的直线生成算法和整圆生成算法完整代码
Bresenham的直线生成算法和整圆生成算法完整代码以下是Bresenham的直线生成算法和整圆生成算法,已调试过,没有任何问题。
Bresenham直线生成算法#include "stdio.h"#include "graphics.h"Bresenham_line(x0,y0,x1,y1,color)int x0,y0,x1,y1,color;{int x,y,dx,dy, i; float k,e;dx=x1-x0;dy=y1-y0;k=(dy*1.0)/dx; e=-0.5; x=x0; y=y0;for (x=x0; x<=x1; x++){putpixel(x,y,color);e=e+k;if(e>=0){ y++;e=e-1;}}}int main(){int x0,y0,x1,y1,c;int driver=DETECT,mode=0;initgraph(&driver,&mode,"c:\\tc");setbkcolor(BLUE);setcolor(YELLOW);printf("input x0,y0,x1,y1,c");scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&c);Bresenham_line(x0,y0,x1,y1,c);closegraph();}当取e=2*dy-dx时,可以消除浮点和除法运算#include "stdio.h"#include "graphics.h"Bresenham_line(x0,y0,x1,y1,color)int x0,y0,x1,y1,color;{int x,y,dx,dy, i,e; float k;dx=x1-x0;dy=y1-y0;k=(dy*1.0)/dx; e=2*dy-dx; x=x0; y=y0;for (x=x0; x<=x1; x++){putpixel(x,y,color);e=e+2*dy;if(e>=0){ y++;e=e-2*dx;}}}int main(){int x0,y0,x1,y1,c;int driver=DETECT,mode=0;initgraph(&driver,&mode,"c:\\tc"); setbkcolor(BLUE);setcolor(YELLOW);printf("input x0,y0,x1,y1,c");scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&c); Bresenham_line(x0,y0,x1,y1,c);closegraph();}Bresenham整圆生成算法#include "stdio.h"#include "graphics.h"void circlePoints(int x0,int y0,int x,int y,int color) { putpixel(x+x0,y+y0,color);putpixel(x+x0,-y+y0,color);putpixel(y+x0,x+y0,color);putpixel(y+x0,-x+y0,color);putpixel(-x+x0,-y+y0,color);putpixel(-x+x0,y+y0,color);putpixel(-y+x0,-x+y0,color);putpixel(-y+x0,x+y0,color);}Bresenhamcircle (int x0,int y0,int r){int x,y,d,color=15;d=3-2*r;x=0;y=r; /*从(0,r)开始画圆*/?circlePoints(x0,y0,x,y,color);while(x<y)< p="">{if(d<0){d=d+4*x+6;x++;}else{d= d+4*(x-y)+10;x++;y--;}circlePoints(x0,y0,x,y,color);}}main(){int r,x0,y0;int driver=DETECT,mode=0; initgraph(&driver,&mode,"c:\\tc"); setbkcolor(BLUE);setcolor(YELLOW);printf("input x0,y0,r\n");scanf("%d%d%d",&x0,&y0,&r); Bresenhamcircle(x0,y0,r);getch();closegraph();}</y)<>。
Bresenham直线算法与画圆算法(转)
Bresenham直线算法与画圆算法(转)在我们内部开发使用的一个工具中,我们需要几乎从0 开始实现一个高效的二维图像渲染引擎。
比较幸运的是,我们只需要画直线、圆以及矩形,其中比较复杂的是画直线和圆。
画直线和圆已经有非常多的成熟的算法了,我们用的是Bresenham的算法。
计算机是如何画直线的?简单来说,如下图所示,真实的直线是连续的,但我们的计算机显示的精度有限,不可能真正显示连续的直线,于是我们用一系列离散化后的点(像素)来近似表现这条直线。
(上图来自于互联网络,《计算机图形学的概念与方法》柳朝阳,郑州大学数学系)接下来的问题就是如何尽可能高效地找到这些离散的点,Bresenham直线算法就是一个非常不错的算法。
Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在n维光栅上最接近的点。
这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。
是计算机图形学中最先发展出来的算法。
(引自wiki 百科布雷森漢姆直線演算法)这个算法的流程图如下:可以看到,算法其实只考虑了斜率在 0 ~ 1 之间的直线,也就是与 x 轴夹角在 0 度到 45 度的直线。
只要解决了这类直线的画法,其它角度的直线的绘制全部可以通过简单的坐标变换来实现。
下面是一个C 语言实现版本。
1 2 3 4 5 // 交换整数 a 、b 的值inline void swap_int(int *a, int *b) {*a ^= *b;*b ^= *a;*a ^= *b;6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 }// Bresenham's line algorithmvoid draw_line(IMAGE *img, int x1, int y1, int x2, int y2, unsigned long c) {// 参数 c 为颜色值int dx = abs(x2 - x1),dy = abs(y2 - y1),yy = 0;if (dx < dy) {yy = 1;swap_int(&x1, &y1);swap_int(&x2, &y2);swap_int(&dx, &dy);}int ix = (x2 - x1) > 0 ? 1 : -1,iy = (y2 - y1) > 0 ? 1 : -1,cx = x1,cy = y1,n2dy = dy * 2,n2dydx = (dy - dx) * 2,d = dy * 2 - dx;if (yy) { // 如果直线与 x 轴的夹角大于 45 度while (cx != x2) {if (d < 0) {d += n2dy;} else {cy += iy;d += n2dydx;}putpixel(img, cy, cx, c);cx += ix;}} else { // 如果直线与 x 轴的夹角小于 45 度while (cx != x2) {if (d < 0) {d += n2dy;} else {cy += iy;d += n2dydx;}50515253putpixel(img, cx, cy, c);cx += ix;}}}可以看到,在画线的循环中,这个算法只用到了整数的加法,所以可以非常的高效。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//
//
//
//
//
//
//
///////////////////////////////////////////////////////////////////
void BresenhamLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1,
GLsizei num)
{ glVertex2f((float)(i), -250.0f); glVertex2f((float)(i), 250.0f); glVertex2f(-250.0f, (float)(i)); glVertex2f(250.0f, (float)(i));
} glEnd(); }
//绘制一个点,这里用一个正方形表示一个点 void putpixel(GLsizei x, GLsizei y) {
return;
//画线算法的实现
GLsizei dx,dy,epsl,k; GLfloat x,y,xIncre,yIncre;
dx = x1-x0; dy = y1-y0; x = x0; y = y0;
if(abs(dx) > abs(dy)) epsl = abs(dx); else epsl = abs(dy); xIncre = (float)dx / epsl ; yIncre = (float)dy / epsl ;
#include <windows.h> #include <gl/glut.h> #include "stdio.h"
int m_PointNumber = 0; //动画时绘制点的数目
int m_DrawMode = 1; //绘制模式 1 DDA算法画直线
//
2 中点Bresenham算法
画直线
putpixel(x,y); if (p>=num-1) { printf("x=%d,y=%d\n", x, y); break; } p++; x++; if(d<0){
y++; d+=UpIncre; } else d+=DownIncre; } } if(k>1){ d=dy-2*dx; UpIncre=2*dy-2*dx; DownIncre=-2*dx; while(y<=y1){
void DDACreateLine(GLsizei x0, GLsizei y0, GLsizei x1, GLsizei y1,
GLsizei num)
{
//设置颜色
glColor3f(1.0f,0.0f,0.0f);
//对画线动画进行控制 if(num == 1) printf("DDA画线算法:各点坐标\n"); else if(num==0)
for(k = 0; k<=epsl; k++){ putpixel((int)(x+0.5), (int)(y+0.5)); if (k>=num-1) { printf("x=%f , y=%f,取整后 x=%d,y=%d\n", x, y,
(int)(x+0.5),(int)(y+0.5)); break;
glRectf(10*x,10*y,10*x+10,10*y+10); }
/////////////////////////////////////////////////////////////////// //DDA画线算法
//
//
//
//
//
//
//
///////////////////////////////////////////////////////////////////
putpixel(x,y); if (p>=num-1) {
printf("x=%d,y=%d\n", x, y); break; } p++;
x++; if(d>0){
y--; d+=DownIncre; } else d+=UpIncre; } } if(k<-1){ d=-dy-2*dx; UpIncre=-2*dx-2*dy; DownIncre=-2*dx; while(y>=y1){
//
3 改进Bresenham算法
画直线
//
4 八分法绘制圆
//
5 四分法绘制椭圆
//绘制坐标线 void DrawCordinateLine(void) {
int i = -250 ; //坐标线为黑色 glColor3f(0.0f, 0.0f ,0.0f);
glBegin(GL_LINES); for (i=-250;i<=250;i=i+10)
}
x += xIncre; y += yIncre;
if(x >= 25 || y >= 25) break; }
}
///////////////////////////////////////////////////////////////////
//中点Bresenham算法画直线(0<=k<=1)
x=x1;x1=x0;x0=x; y=y1;y1=y0;y0=y; } x=x0;y=y0; dx=x1-x0;dy=y1-y0; k=dy/dx; if(k>=0&&k<=1){ d=dx-2*dy; UpIncre=2*dx-2*dy; DownIncre=-2*dy; while(x<=x1){
putpixel(x,y); if (p>=num-1) {
printf("x=%d,y=%d\n", x, y); break; } p++; y++; if(d<0){
x++; d+=UpIncre; } else d+=DownIncre; } } if(k<0&&k>=-1){ d=dx-2*dy; UpIncre=-2*dy; DownIncre=-2*dx-2*dy; while(x<=x1){
{
glColor3f(1.0f,0.0f,0.0f);
if(num == 1)
Hale Waihona Puke printf("中点Bresenham算法画直线各点坐标及判别式的值\n"); else if(num==0)
return;
//画线算法的实现 GLsizei p=0; GLfloat UpIncre,DownIncre,x,y,d,k,dx,dy; if(x0>x1){