计算机图形学实验报告-直线中点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 :。
计算机图形学实验报告

武汉工业学院数学与计算机学院《计算机图形学》实验报告专业:班级:学号:姓名:指导老师:2012年5月25日第二章直线生成算法2.1 实验原理2.1.1 中点Bresenham算法2.2 实验内容请使用中点Bresenham算法来生成直线。
实验环境:Turboc 或Visual C++2.3 程序代码void CTest1View::BresenhamLine(CDC* pDC,int x0,int y0,int x1,int y1) {int color=RGB(250,0,0);//k为直线的斜率float k=(y1-y0)/(x1-x0);//d为中点偏差判别式float d=0.5-k;int x;int y=y0;for (x=x0; x<=x1; x++){pDC->SetPixel(x, y, color);if(d<0){y=y+1;d=d+1-k;}else{d=d-k;}}}2.4运行结果\2.5心得体会通过本次实验我学会了很多东西,例如:熟悉了在VC++环境下开发图形程序的流程,学会了在类的view里面创建新的绘图函数,然后在ondraw函数中调用自己创建的绘图函数来实现绘图算法,本次实验首先运行了DDA算法,再通过Bresenham算法的原理,编写了Bresenham算法的绘图函数,熟悉了直线的两种绘,这次试验是今后图形学试验的基础,所以掌握好了这次知识点,无疑是为今后的试验作铺垫。
第三章圆弧生成算法3.1 实验原理中点算法Bresenham算法3.2 实验内容用上述每一种算法来实现圆弧的生成。
每一种算法的实现用一个函数来表示。
实验环境:Turboc 或Visual C++。
3.3程序代码void CTest2View::myCircle(CDC* pDC,float n,float m,float r) {int color=RGB(250,0,0);int a,b;int f,x,y;a=0;b=0;f=0;x=a;y=b+r;while(y>b){pDC->SetPixel(x+n,-y+m,color);pDC->SetPixel(-x+n,-y+m,color);pDC->SetPixel(-x+n,y+m,color);pDC->SetPixel(x+n,y+m,color);if (f>0){f=f-2*(y-b)+1;y=y-1;}else{f=f+2*(x-a)+1;x++;}}if (y==b){pDC->SetPixel(x+n,y+m,color);pDC->SetPixel(-x+n,y+m,color);pDC->SetPixel(x+n,-y+m,color);pDC->SetPixel(-x+n,-y+m,color);}}3.1.2 Bresenham算法void CTest2View::BersenhamCircle(CDC* pDC,float n,float m,float r) {int color=RGB(250,0,0);float a,b;float f,x,y;a=0;b=0;f=1.25-r;x=a;y=b+r;while(y>x){pDC->SetPixel(x+n,-y+m,color);pDC->SetPixel(-x+n,-y+m,color);pDC->SetPixel(-x+n,y+m,color);pDC->SetPixel(x+n,y+m,color);pDC->SetPixel(y+n,-x+m,color);pDC->SetPixel(-y+n,-x+m,color);pDC->SetPixel(-y+n,x+m,color);pDC->SetPixel(y+n,x+m,color);if (f>0){f=f+2*(x-y)+5;y=y-1;x++;}else{f=f+2*x+3;x++;}}}3.3运行结果3.4 心得体会本次实验是参考老师提供的参考程序和课本中绘制1/8圆的中点Bresenham 算法原理完成的,通过对绘制1/8圆的算法原理进行修改,同时绘制8个1/8圆,能够化整为零,描绘出一个完整的圆形。
计算机图形学实验报告3 - Bresenham画线

在大括号内填入以下代码
CDC *pDC=GetDC();
int k;
double x1=10,y1=10,x2=200,y2=150;
double x,y,deltx,delty,E;
deltx=x2-x1;delty=y2-y1;
x=x1;y=y1;k=1;
if(deltx>0&&delty>0)
3.Object IDs选择ID_Bresenham,Messages选择COMMAND
4.点击Add Function,点击OK,点击Edit Code,进入编辑函数的界面([项目名]View.cpp)
void C[项目名]View::OnBresenham()
{
// TODO: Add your command handler code here
实验要求:
掌握Bresenham画线算法
实验仪器:
软件:VC++6.0,windows XP
硬件:计算机
实验步骤、内容:
一、新建MFC工程
1.开始所有程序Microsoft Visual C++ 6.0Microsoft Visual C++ 6.0
2.文件-->新建-->工程,工程名称填[项目名],左边的类型选择MFC AppWizard [exe],点击确定
{
if(fabs(deltx)>fabs(dfor(k=1;k<=fabs((int)deltx);k++)
{
pDC->SetPixel((int)x,(int)y,RGB(0,0,0));
E+=(2*delty);
《计算机图形学》实验指导书

计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现DDA、中点画线算法和Bresenham画线算法 (24)实验二实现Bezier曲线 (25)实验三实现B样条曲线 (26)实验四实现多边形填充的边界标志算法 (27)实验五实现裁剪多边形的Cohen-Sutherland算法 (28)实验六二维图形的基本几何变换 (30)实验七画图软件的编制 (31)实验一实现DDA、中点画线算法和Bresenham画线算法【实验目的】1、掌握直线的多种生成算法;2、掌握二维图形显示原理。
【实验环境】VC++6.0/ BC【实验性质及学时】验证性实验,2学时,必做实验【实验内容】利用任意的一个实验环境,编制源程序,分别实现直线的三种生成算法,即数字微分法(DDA)、中点画线法以及Bresenham画线算法。
【实验原理】1、数字微分法(Digital Differential Analyzer,DDA)算法思想:基于直线的微分方程来生成直线。
ε=1/max(|△x|,|△y|)max(|△x|,|△y|)=|△x|,即|k|≤1 的情况:max(|△x|,|△y|)=|△y|,此时|k|≥1:2、中点画线法算法思想:每次在最大位移方向上走一步,另一方向是否走步取决于误差项的判断。
3、Bresenham画线算法算法思想:其基本思想同中点算法一样,即每次在最大位移方向上走一步,而另一个方向是否走步取决于误差项的判断。
【实验要求】1.上交源程序;2.上交实验报告,实验报告内容如下:(1) 实验名称(2) 实验目的(3) 算法实现的设计方法及程序流程图(4) 程序结果分析【分析与思考】(1) 上述所阐述的三个算法,其基本算法只能适用于直线的斜率(|K|<=1) 的情形,如何将上述算法进行推广,使其能够处理任意斜率的直线?(2) 计算机显示屏幕的坐标圆心在哪里,与我们平时的习惯有什么差异,如何协调二者?实验二 实现Bezier 曲线【实验目的】1、掌握Bezier 曲线的定义;2、能编程实现N 次Bezier 曲线的绘制与显示。
计算机图形学课程设计实验报告

计算机图形学课程设计实验报告SHANDONG. UNIVERsrrr OF SCIENCE ^ND TECHNOLOGY《计算机图形学》实验报告班级计算机科学与技术姓名学号实验一基本图形生成算法一、实验目的:1、掌握中点Bresenham 绘制直线的原理;2、设计中点Bresenham 算法;3、掌握八分法中点Bresenham 算法绘制圆的原理;4、设计八分法绘制圆的中点Bresenham 算法;5 、掌握绘制1/4 椭圆弧的上半部分和下半部分的中点Bresenham 算法原理;6、掌握下半部分椭圆偏差判别式的初始值计算方法;7、设计顺时针四分法绘制椭圆的中点Bresenham 算法。
二、实验过程:1、实验描述实验1:使用中点Bresenham 算法绘制斜率为0<=k<=1 的直线。
实验2:使用中点Bresenham 算法绘制圆心位于屏幕客户区中心的圆。
实验3:使用中点Bresenham 算法绘制圆心位于屏幕客户区中心的椭圆。
2、实验过程1)用MFC(exe建立一个单文档工程;2)编写对话框,生成相应对象,设置相应变量;3)在类CLineView 中声明相应函数,并在相关的cpp 文件中实现;4) 在OnDraw ()函数里调用函数实现绘制直线、圆、椭圆;5) 运行程序,输入相应值,绘制出图形。
三、源代码实验1:直线中点Bresenham 算法1.// cline.cpp : implementation file// cline dialog cline::cline(CWnd* pParent /*=NULL*/): CDialog(cline::IDD, pParent){//{{AFX_DATA_INIT(cline) m_x0 = 0;m_y0 = 0;m_x1 = 0;m_y1 = 0; //}}AFX_DATA_INIT}void cline::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(cline)DDX_Text(pDX, IDC_x0, m_x0); DDX_Text(pDX, IDC_y0, m_y0);DDX_Text(pDX, IDC_x1, m_x1); DDX_Text(pDX, IDC_y1, m_y1);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(cline, CDialog)//{{AFX_MSG_MAP(cline) //}}AFX_MSG_MAPEND_MESSAGE_MAP()2、// LineView.hclass CLineView : public CView{public:CLineDoc* GetDocument();。
实验1:Bresenham算法

实验1:Bresenham算法计科102班蓝广森 1007300441 一、实验目的:掌握Bresenham直线扫描算法二、实验内容和要求:实现绘制各种情况直线的Bresenham算法,并将实现的算法应用于任意多边形的绘制,要求多边形的顶点由键盘输入或鼠标拾取,绘制的多边形顶点要准确,图形应该封闭。
要求掌握Bresenham算法的基本原理和算法设计,画出算法实现的程序流程图,使用C或者VC++实现算法,并演示。
三、实验原理:算法的基本描述// 假设该线段位于第一象限内且斜率大于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.结束直线实现原理这里需要细化的是怎么判断下个要画的点为当前点的右邻接点还是当前点的右上邻接点四、实验流程图:五、关键代码:void CB08021730View::OnMenuline(){// TODO: Add your command handler code hereInputDlg dlg;if(dlg.DoModal()==IDOK){x1=dlg.m_x1;y1=dlg.m_y1;x2=dlg.m_x2;y2=dlg.m_y2;}AfxGetMainWnd()->SetWindowText("Bresenham算法");RedrawWindow();Bresenham();}void CB08021730View::Brensenham(){CClientDC dc(this);CRect Rect;//定义矩形对象GetClientRect(&Rect);//获得当前窗口的客户区大小dc.SetMapMode(MM_ANISOTROPIC);//设置MM_ANISOTROPIC映射模式dc.SetWindowExt(Rect.Width(),Rect.Height());//设置窗口范围dc.SetViewportExt(Rect.Width(),-Rect.Height());//设置视区范围dc.SetViewportOrg(Rect.Width()/2,Rect.Height()/2);//设置视口原点dc.MoveTo(-Rect.Width(),0);dc.LineTo (Rect.Width(),0);dc.MoveTo(0,-Rect.Height()/2);dc.LineTo (0,Rect.Height()/2);COLORREF rgb=RGB(0,255,0);//定义直线颜色double x,y;double d,k;k=(y2-y1)/(x2-x1);if(0<=k && k<=1)//直线斜率[0,1]时{if(x1>x2){double tx=x1;double ty=y1;x1=x2;y1=y2;x2=tx;y2=ty;}x=x1;y=y1;d=0.5-k;for(x=x1;x<=x2;x++){dc.SetPixel(ROUND(x),ROUND(y),rgb); if(d<0){y++;d+=1-k;}elsed-=k;}}if(k>1) // 直线斜率k>1时{if(y1>y2){double tx=x1;double ty=y1;x1=x2;y1=y2;x2=tx;y2=ty;}x=x1;y=y1;d=1-0.5*k;for(y=y1;y<=y2;y++){dc.SetPixel(ROUND(x),ROUND(y),rgb);if(d>=0){x++;d+=1-k;}elsed+=1;}}if(k<-1) //直线斜率k<-1时{if(y1<y2){double tx=x1;double ty=y1;x1=x2;y1=y2;x2=tx;y2=ty;}x=x1;y=y1;d=-1-0.5*k;for(y=y1;y>y2;y--){dc.SetPixel(ROUND(x),ROUND(y),rgb);if(d<0){x++;d-=1+k;}elsed-=1;}}if(-1<=k && k<0) //直线斜率[-1,0]时{if(x1>x2){double tx=x1;double ty=y1;x1=x2;y1=y2;x2=tx;y2=ty;}x=x1;y=y1;d=-0.5-k;for(x=x1;x<=x2;x++){dc.SetPixel(ROUND(x),ROUND(y),rgb); if(d>0){y--;d-=1+k;}elsed-=k;}}if(fabs(x1-x2)<1e-6){if(y1>y2){double tx=x1;double ty=y1;x1=x2;y1=y2;x2=tx;y2=ty;}x=x1;y=y1;for(y=y1; y<y2;y++){dc.SetPixel (ROUND(x),ROUND(y),rgb);}}}六、实验分析:1实验结果图设置初始化坐标Bresenham算法实现的直线2实验收获掌握利用Visual C++进行图形程序设计的方法以及简单的图形画法,并编程实现Bresenham直线扫描转换程序,得出相应的输出图形。
计算机图形学课程设计实验报告

《计算机图形学》实验报告班级计算机科学与技术姓名学号2014 年6 月2 日实验一基本图形生成算法一、实验目的:1、掌握中点Bresenham绘制直线的原理;2、设计中点Bresenham算法;3、掌握八分法中点Bresenham算法绘制圆的原理;4、设计八分法绘制圆的中点Bresenham算法;5、掌握绘制1/4椭圆弧的上半部分和下半部分的中点Bresenham算法原理;6、掌握下半部分椭圆偏差判别式的初始值计算方法;7、设计顺时针四分法绘制椭圆的中点Bresenham算法。
二、实验过程:1、实验描述实验1:使用中点Bresenham算法绘制斜率为0<=k<=1的直线。
实验2:使用中点Bresenham算法绘制圆心位于屏幕客户区中心的圆。
实验3:使用中点Bresenham算法绘制圆心位于屏幕客户区中心的椭圆。
2、实验过程1)用MFC(exe)建立一个单文档工程;2)编写对话框,生成相应对象,设置相应变量;3)在类CLineView中声明相应函数,并在相关的cpp文件中实现;4)在OnDraw()函数里调用函数实现绘制直线、圆、椭圆;5)运行程序,输入相应值,绘制出图形。
三、源代码实验1:直线中点Bresenham算法1.// cline.cpp : implementation file// cline dialogcline::cline(CWnd* pParent /*=NULL*/): CDialog(cline::IDD, pParent){//{{AFX_DATA_INIT(cline)m_x0 = 0;m_y0 = 0;m_x1 = 0;m_y1 = 0;//}}AFX_DATA_INIT}void cline::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(cline)DDX_Text(pDX, IDC_x0, m_x0);DDX_Text(pDX, IDC_y0, m_y0);DDX_Text(pDX, IDC_x1, m_x1);DDX_Text(pDX, IDC_y1, m_y1);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(cline, CDialog)//{{AFX_MSG_MAP(cline)//}}AFX_MSG_MAPEND_MESSAGE_MAP()2、// LineView.hclass CLineView : public CView{public:CLineDoc* GetDocument();..........void Mbline(double,double,double,double); //直线中点Bresenham函数.......}3、// Line.cpp//*******************直线中点Bresenham函数*********************/void CLineView::Mbline(double x0, double y0, double x1, double y1) {CClientDC dc(this);COLORREF rgb=RGB(0,0,255); //定义直线颜色为蓝色double x,y,d,k;x=x0; y=y0; k=(y1-y0)/(x1-x0); d=0.5-k;for(x=x0;x<=x1;x++){dc.SetPixel((int)x,(int)y,rgb);if(d<0){y++;d+=1-k;}elsed-=k;}}4、//LineView.cppvoid CLineView::OnDraw(CDC* pDC){CLineDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data herecline a;a.DoModal();//初始化CLineView::Mbline(a.m_x0,a.m_y0,a.m_x1,a.m_y1); }实验2:圆中点Bresenham算法1、//cricle.cpp// Ccricle dialogCcricle::Ccricle(CWnd* pParent /*=NULL*/): CDialog(Ccricle::IDD, pParent){//{{AFX_DATA_INIT(Ccricle)m_r = 0;//}}AFX_DATA_INIT}void Ccricle::DoDataExchange(CDataExchange* pDX) {CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(Ccricle)DDX_Text(pDX, r_EDIT, m_r);//}}AFX_DATA_MAP}2、//CcircleView.hclass CCcircleView : public CView{.......public:CCcircleDoc* GetDocument();void CirclePoint(double,double); //八分法画圆函数void Mbcircle(double); //圆中点Bresenham函数........}3、//CcircleView.cppvoid CCcircleView::OnDraw(CDC* pDC){CCcircleDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCcricle r;r.DoModal();CCcircleView::Mbcircle(r.m_r);//画圆}4、//CcircleView.cpp//*******************八分法画圆*************************************/ void CCcircleView::CirclePoint(double x,double y){CClientDC dc(this);COLORREF rgb=RGB(0,0,255);dc.SetPixel((int)(300+x),(int)(300+y),rgb);dc.SetPixel((int)(300-x),(int)(300+y),rgb);dc.SetPixel((int)(300+x),(int)(300-y),rgb);dc.SetPixel((int)(300-x),(int)(300-y),rgb);dc.SetPixel((int)(300+y),(int)(300+x),rgb);dc.SetPixel((int)(300-y),(int)(300+x),rgb);dc.SetPixel((int)(300+y),(int)(300-x),rgb);dc.SetPixel((int)(300-y),(int)(300-x),rgb);}//**************************圆中点Bresenham函数*********************/ void CCcircleView::Mbcircle(double r){double x,y,d;COLORREF rgb=RGB(0,0,255);d=1.25-r;x=0;y=r;for(x=0;x<y;x++){CirclePoint(x,y); //调用八分法画圆子函数if(d<0)d+=2*x+3;else{d+=2*(x-y)+5;y--;}}}实验3:椭圆中点Bresenham算法1、//ellipse1.cpp// Cellipse dialogCellipse::Cellipse(CWnd* pParent /*=NULL*/) : CDialog(Cellipse::IDD, pParent){//{{AFX_DATA_INIT(Cellipse)m_a = 0;m_b = 0;//}}AFX_DATA_INIT}void Cellipse::DoDataExchange(CDataExchange* pDX) {CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(Cellipse)DDX_Text(pDX, IDC_EDIT1, m_a);DDX_Text(pDX, IDC_EDIT2, m_b);//}}AFX_DATA_MAP}2、//EllipseView.hclass CEllipseView : public CView{......................public:CEllipseDoc* GetDocument();void EllipsePoint(double,double); //四分法画椭圆void Mbellipse(double a, double b); //椭圆中点Bresenham函数..................}3、//Ellipse.cpp//*****************四分法画椭圆********************************/void CEllipseView::EllipsePoint(double x,double y){CClientDC dc(this);COLORREF rgb=RGB(0,0,255);dc.SetPixel((int)(300+x),(int)(300+y),rgb);dc.SetPixel((int)(300-x),(int)(300+y),rgb);dc.SetPixel((int)(300+x),(int)(300-y),rgb);dc.SetPixel((int)(300-x),(int)(300-y),rgb);}//************************椭圆中点Bresenham函数*********************/ void CEllipseView::Mbellipse(double a, double b){double x,y,d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.25);EllipsePoint(x,y);while(b*b*(x+1)<a*a*(y-0.5))//椭圆AC弧段{if(d1<0)d1+=b*b*(2*x+3);else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);y--;}x++;EllipsePoint(x,y);}d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;//椭圆CB弧段while(y>0){if(d2<0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;}elsed2+=a*a*(-2*y+3);y--;EllipsePoint(x,y);}}4、//EllipseView.cppvoid CEllipseView::OnDraw(CDC* pDC){CEllipseDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data hereCellipse el;el.DoModal();//初始化CEllipseView::Mbellipse(el.m_a, el.m_b);//画椭圆}四、实结果验实验1:直线中点Bresenham算法实验2:圆中点Bresenham算法实验3:椭圆中点Bresenham算法实验二有效边表填充算法一、实验目的:1、设计有效边表结点和边表结点数据结构;2、设计有效边表填充算法;3、编程实现有效边表填充算法。
计算机图形学实验数值微分(DDA)法中点画线法Bresenham算法

计算机图形学实验数值微分(DDA)法中点画线法Bresenham算法实验名称数值微分(DDA)法、中点画线法、Breenham算法实验时间年月日专业姓名学号预习操作座位号教师签名总评一、实验目的:1.了解数值微分(DDA)法、中点画线法、Breenham算法的基本思想;2.掌握数值微分(DDA)法、中点画线法、Breenham算法的基本步骤;二、实验原理:1.数值微分(DDA)法y1y0k已知过端点P00,y(某的直线段L:y=k某+b,直线斜率为(某0),P11,y1)某1某0某从某的左端点0开始,向某右端点步进。
步长=1(个象素),计算相应的y坐标y=k某+b;取象素点(某,round(y))作为当前点的坐标。
2.中点画线法当前象素点为(某p,yp)下一个象素点为P1或P2设M=(某p+1,yp+0.5),为p1与p2之中点,Q为理想直线与某=某p+1垂线的交点。
将Q与M的y坐标进行比较。
当M在Q的下方,则P2应为下一个象素点;当M在Q的上方,应取P1为下一点。
构造判别式:d=F(M)=F(某p+1,yp+0.5)=a(某p+1)+b(yp+0.5)+c,其中a=y0-y1,b=某1-某0,c=某0y1-某1y0。
当d<0,M在L(Q点)下方,取右上方P2为下一个象素;当d>0,M在L(Q点)上方,取右方P1为下一个象素;当d=0,选P1或P2均可,约定取P1为下一个象素;但这样做,每一个象素的计算量是4个加法,两个乘法。
d是某p,yp的线性函数,因此可采用增量计算,提高运算效率。
若当前象素处于d0情况,则取正右方象素P1(某p+1,yp),要判下一个象素位置,应计算d1=F(某p+2,yp+0.5)=a(某p+2)+b(yp+0.5)=d+a;增量为a。
若d<0时,则取右上方象素P2(某p+1,yp+1)。
要判断再下一象素,则要计算d2=F(某p+2,yp+1.5)=a(某p+2)+b(yp+1.5)+c=d+a+b;增量为a+b。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机图形学实验报告
实验内容直线中点Bresenham算法的实现专业计算机科学与技术
班级
学号
姓名
指导教师刘长松
年月日
一、实验题目
直线中点Bresenham算法的实现
二、实验要求
学习Visual C++ 6.0集成编程环境的使用、图形设备接口和常用图形程序设计、鼠标编程以及菜单设计等基础知识,从而掌握利用Visual C++进行图形程序设计的方法以及简单的图形画法,并编程实现Bresenham直线扫描转换程序,得出相应的输出图形。
三、实验内容
1.学习Visual C++ 6.0集成编成环境的使用;
2.掌握Visual C++ 6.0图形设备接口和常用图形程序设计、菜单设计等方法;
3.编程实现Bresenham直线扫描转换程序,得出相应的输出图形;
四、实验过程
1、实验原理
Bresenham 算法思想:
0≤d≤1
当d<0.5:下一个象素应取右光栅点(xi+1,yi)
当d≥0.5:下一个象素应取右上光栅点(xi+1,yi+1)
e=d-0.5 假定直线斜率|k|≤1。
e0= -0.5,x每次加1,e = e + k;e<0时,下一像素取(xi+1,yi),e = e + k ;e>0时,下一像素取(xi+1,yi+1);
e = e + k -1 ;e=0时,可任取上、下光栅点显示。
当斜率|k|>1时,同理,只是y每次加1,x是否变化取决于增量e。
中点算法
d =2F(M)=2F(Xp+1,Yp+0.5)=2(a(Xp+1)+b(Yp+0.5)+c) 其中a=y0-y1, b=x1-x0, c=x0y1-x1y0
当d<0,M在L(Q点)下方,取右上方T为下一个象素;
此时再下一个象素的判别式为:
d’= 2F(Xp+2,Yp+0.5)=2(a(Xp+2)+b(Yp+0.5)+c)
= 2(a(Xp+1)+b(Yp+0.5)+c) +2a = d + 2a; 当d>0,M在L(Q点)上方,取右方B为下一个象素;
此时下一个象素的判别式为:
d’= 2F(Xp+2,Yp+1.5)=2(a(Xp+2)+b(Yp+1.5)+c)
= 2(a(Xp+1)+b(Yp+0.5)+c) +2(a +b) = d + 2(a + b); 当d=0,选T或B均可,约定取B为下一个象素;d0 = 2F(X0+1,Y0+0.5) = 2(a(X0+1)+b(Y0+0.5)+c)
= 2(F(X0,Y0)+a+0.5b)
2、案例分析
MFC提供的CDC类的成员函数MoveTo()和LineTo()函数用于绘制傻
任意斜率的直线段,直线段的颜色由所选用的画笔指定。
MoveTo()函数移动当前点到参数(x,y)所指定的点,不画线;LineTo()函数从当前点画一直线段到参数(x,y)所指定的点,但不包括(x,y)。
本案例通过定义Cline类来模拟CDC类绘制任意斜的直线段,采用直线中点Bresenham算法。
3、算法设计
对于0≤o1的直线段,中点Bresenham算法如下:
(1)使用鼠标选择起点坐标p0(x0,y0)和终点坐标p1(x1,y1)。
要求起点的的坐标小于等于终点的x坐标。
(2)定义直线段当前点坐标x,y,定义中点误差项d,定义直线斜k,定义像素点颜色clr。
(3)x=x0,y=y0,计算d=0.5-k,k=(y1-y0)/(x1-x0), clr=CRGB(0,0,1)
(4)绘制点(x,y),判断d的符号。
若d<0,则(x,y)更新为(x+1,y+1),d更新为d+1-k;否则(x,y)更新为(x+1,y),d更新为d-k。
(5)如果当前点x<x1,重复步骤(4),否则结束。
4、主要代码
// Line.cpp: implementation of the CLine class.
#include "stdafx.h"
#include "Line.h"
#include "math.h"
#define Round(d) int(floor(d+0.5))//四舍五入宏定义
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
CLine::CLine()
{
}
CLine::~CLine()
{
}
void CLine::MoveTo(CDC *pDC,CP2 p0)//绘制直线起点函数
{
P0=p0;
}
void CLine::MoveTo(CDC *pDC,double x0,double y0)//重载函数{
P0=CP2(x0,y0);
}
void CLine::LineTo(CDC *pDC,CP2 p1)
{
P1=p1;
CP2 p,t;
CRGB clr=CRGB(0.0,0.0,0.0);//黑色像素点
if(fabs(P0.x-P1.x)<1e-6)//绘制垂线
{
if(P0.y>P1.y)//交换顶点,使得起始点低于终点
{
t=P0;P0=P1;P1=t;
}
for(p=P0;p.y<P1.y;p.y++)
{
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(clr.red*255,clr.green*255,clr.blue *255));
}
}
else
{
double k,d;
k=(P1.y-P0.y)/(P1.x-P0.x);
if(k>1.0)//绘制k>1
{
if(P0.y>P1.y)
{
t=P0;P0=P1;P1=t;
}
d=1-0.5*k;
for(p=P0;p.y<P1.y;p.y++)
{
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(clr.red*255,clr.green*255,clr.blue *255));
if(d>=0)
{
p.x++;
d+=1-k;
}
else
d+=1;
}
}
if(0.0<=k && k<=1.0)//绘制0<=k<=1
{
if(P0.x>P1.x)
{
t=P0;P0=P1;P1=t;
}
d=0.5-k;
for(p=P0;p.x<P1.x;p.x++)
{
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(clr.red*255,clr.green*255,clr.blue *255));
if(d<0)
{
p.y++;
d+=1-k;
}
else
d-=k;
}
}
if(k>=-1.0 && k<0.0)//绘制-1<=k<0
{
if(P0.x>P1.x)
{
t=P0;P0=P1;P1=t;
}
d=-0.5-k;
for(p=P0;p.x<P1.x;p.x++)
{
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(clr.red*255,clr.green*255,clr.blue *255));
if(d>0)
{
p.y--;
d-=1+k;
}
else
d-=k;
}
}
if(k<-1.0)//绘制k<-1
{
if(P0.y<P1.y)
{
t=P0;P0=P1;P1=t;
}
d=-1-0.5*k;
for(p=P0;p.y>P1.y;p.y--)
{
pDC->SetPixelV(Round(p.x),Round(p.y),RGB(clr.red*255,clr.green*255,clr.blue *255));
if(d<0)
{
p.x++;
d-=1+k;
}
else
d-=1; }}}
P0=p1;
}
void CLine::LineTo(CDC *pDC,double x1,double y1)//重载函数
{
LineTo(pDC,CP2(x1,y1));
}
程序运行时如所示图5-1结果
图5-1 点击绘图按钮是会出现如图5-2所示结果
图5-2 按左键绘图结果如图5-3
图5-3
计算机图形学是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学,研究的是应用计算机产生图像的所有工作,不管图像是静态的还是动态的,可交互的还是固定的
通过本次试验的设计,让我对计算机图形图像处理有了更加深刻的理解,学会了这种绘制直线的算法Bresenham。
Brensenham算法也是较为常用的算法。