计算机图形学--Bresenham完整算法-画直线、椭圆和圆

合集下载

中点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算法画直线

《图形学》实验四:中点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)算法画线

布兰森汉姆(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算法是计算机图形学中常用的一种画直线的算法。

它的原理是利用像素点在屏幕上的排列规律,从而高效地计算出直线上的像素点。

本文将以一个具体的例题来说明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算法的基本原理。

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
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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){
相关文档
最新文档