案例2-直线中点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算法这里不仔细讲原理,只是把我写的算法发出来,跟大家分享下,如果有错误的话,还请大家告诉我,如果写的不好,也请指出来,一起讨论进步。

算法步骤:(1)输入直线的两端点P0(x0,y0)和P1(x1,y1)。

(2)计算初始值dx,dy,e=-dx,x=x0,y=y0。

(3)绘制点(x,y)。

(4)e更新为e+2*dy。

判断e的符号,若e 0,则(x,y)更新为(x+1,y+1),同时将e更新为e-2*dx;否则(x,y)更新为(x+1,y)。

(5)当直线没有画完时,重复步骤(3)和(4)否则结束。

水平、垂直和|k|=1的直线可以直接装入帧缓冲存储器面无须进行画线算法处理。

下面是我的算法,如有错误请指出。

#include GL/freeglut.h voidinit(void){glClearColor(0.0f,0.0f,0.0f,1.0f);}void drawLine(intx1,int y1,int x2,int y2){int x,y,dx,dy,e;//k does not existif(x1==x2){if(y1 y2){y=y1;glBegin(GL_POINTS);while(y=y2){glVertex2i(x1,y);++y;}glEnd();}//if(y1 y2)else{y=y2;glBegin(GL_POINTS);while(y=y1){glVertex2i(x1,y);++y;}glEnd();}}//if(x1==x2)else if(y1==y2)//k=0{if(x1 x2){x=x1;glBegin(GL_POINTS);while(x=x2){glVertex2i(x,y1);++x;}glEnd();}//if(x1 x2)else{x=x2;glBegin(GL_POINTS);while(x=x1){glVertex2i(x,y1);++x;}glEnd();}}else{if(x1 x2){int temp=x1;x1=x2;x2=temp;temp=y1;y1=y2;y2=temp;}x=x1;y=y1;dx=x2-x1;dy=y2-y1;//k=1 if(dx==dy){glBegin(GL_POINTS);while(x=x2){glVertex2i(x,y);++x;++y;}glEnd();}else if(dx==-dy)//k=-1{glBegin(GL_POINTS);while(x=x2){glVertex2i(x,y);++x;--y;}glEnd();}else if(dy dx)//k 1{glBegin(GL_POINTS);dx=1;e=-dy;dy=1;y=y1 y2?y2:y1;int maxY=y1 y2?y1:y2;while(y=maxY){glVertex2i(x,y);++y;e+=dx;if(e 0){++x;e-=dy;}}glEnd();}else if(dy 0)//0 k1{e=-dx;dx=1;dy=1;glBegin(GL_POINTS);while(x=x2){glVertex2i(x,y);++x;e+=dy;if(e0){e-=dx;++y;}}glEnd();}else if(-dy dx)//0 k-1{e=-dx;dx=1;dy=1;glBegin(GL_POINTS);while(x=x2){glVertex2i(x,y);++x;e+=dy;if(e0){--y;e+=dx;}}glEnd();}else if(-dy dx)//k-1{e=dy;dx=1;dy=1;glBegin(GL_POINTS);y=y1 y2?y1:y2;int minY=y1 y2?y2:y1;while(y=minY){glVertex2i(x,y);--y;e+=dx;if(e 0){++x;e+=dy;}}glEnd();}}}void display(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0f,0.0f,0.0f);//Vertical line drawLine(0,-200,0,200);//Horizontal line drawLine(-200,0,200,0);//k=1 line drawLine(-200,-200,200,200);//k=-1 line drawLine(-200,200,200,-200);//k=1/2 line drawLine(200,100,-200,-100);//k=2 line drawLine(-100,-200,100,200);//k=-1/2 line drawLine(-200,100,200,-100);//k=-2 line drawLine(-100,200,100,-200);drawLine(30,120,10,70);drawLine(10,70,30,10);drawLine(30,10,60,50);drawLine(60,50,80,10);drawLine(80,10,120,80);drawLine(120,80,70,80);drawLine(70,80,30,120);glutSwapBuffers();}void reshape(int w,inth){glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();if(w=h){gluOrtho2D(-600.0,600.0,-600.0*(GLfloat)h/(GLfloat)w,600.0*(GLfloat)h/(GLfloat)w);}else{gluOr tho2D(-600.0*(GLfloat)w/(GLfloat)h,600.0*(GLfloat)w/(GLfloat)h,-600.0,600.0);}glMatrixMode(GL_MODELVIEW);glLoadIdentity();}void keyboard(unsigned char key,int x,int y){switch(key){case 27://'VK_ESCAPE'exit(0);break;default:break;}}int main(intargc,char*argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);glutInitWindowSize(600,600);glutCreateWindow("optimized Bresenhamline");init();glutReshapeFunc(reshape);glutDisplayFunc(display);glutKeyboardFunc(keyboard);glutMainLoop();return 0;}作者:断桥&残雪发表于2010-12-04 20:29原文链接评论:0查看评论发表评论最新新闻:·马云:B2C创业者别埋怨淘宝不会停下来等你(2010-12-04 20:17)·Chrome to WP7手机端应用程序已经通过审核,可以下载了(2010-12-04 20:00)·盘点网络犯罪与信息战风云30年(2010-12-04 18:06)·网易邮箱:推出简历中心(2010-12-04 18:03)·马云:互联网三座大山将败给创新型小网站(2010-12-04 17:33)编辑推荐:"博客无双"活动:写博客、攒园豆、赢大奖网站导航:博客园首页我的园子新闻闪存小组博问知识库。

bresenham算法实现直线段插值函数

bresenham算法实现直线段插值函数

在计算机图形学中,Bresenham算法是一种用于在离散坐标系上绘制直线段的算法。

它是一种高效的算法,能够准确地计算出直线段上的所有像素点,使得在计算机屏幕上显示出直线段来。

Bresenham算法的实现可以帮助我们更好地理解画线原理,并且在计算机视觉、图像处理等领域有着广泛的应用。

1. Bresenham算法的原理Bresenham算法是通过计算直线段的斜率来确定每个像素点的位置。

具体来说,它利用了直线的对称性和整数的特性,通过计算像素点与真实直线的距离来判断下一个像素点应该取的位置。

这样可以避免使用浮点运算,使得算法更加高效。

2. 实现Bresenham算法的关键步骤在实现Bresenham算法时,需要考虑以下几个关键步骤:- 初始化各个变量,包括起始点(x0, y0)和终点(x1, y1),以及斜率的计算值,例如dx和dy。

- 根据斜率的正负情况,确定每个像素点的增量步长,以便在遍历过程中准确计算出像素点来。

- 利用对称性和整数特性,进行迭代计算,逐步确定直线段上的所有像素点的位置。

3. Bresenham算法的优缺点Bresenham算法作为一种离散直线段插值算法,具有以下几个优点:- 算法简单高效,节省存储空间和运算时间。

- 可以高效地解决像素化显示问题,避免了浮点运算的复杂性。

- 在硬件上实现时,只需少量的资源就能完成计算,适合嵌入式系统和图形处理器。

然而,Bresenham算法也存在一些缺点,比如对于曲线的绘制就不太奏效,因为它是基于直线段的形式来处理的。

4. 我对Bresenham算法的理解在我看来,Bresenham算法是一种经典的离散直线段插值算法,其思想简洁高效。

它通过逐步迭代的方式,计算出直线段上的所有像素点位置,使得在计算机屏幕上显示出直线段来更加精确。

这种算法的实现可以帮助我们更好地理解画线的原理,对于理解计算机图形学和计算机视觉都有着重要的意义。

总结起来,Bresenham算法作为一种高效的离散直线段插值算法,具有着重要的理论和实际价值。

直线的Bresenham算法

直线的Bresenham算法

直线的Bresenham算法本算法由Bresenham在1965年提出。

设直线从起点(x1, y1)到终点(x2, y2)。

直线可表示为方程y=mx+b。

其中b = y1 - m * x1,我们的讨论先将直线方向限于1a象限(图2.1.1)在这种情况下,当直线光栅化时,x每次都增加1个单元,即xi+1=xi+1而y的相应增加应当小于1。

为了光栅化,yi+1只可能选择如下两种位置之一(图2.1.2)。

图2.1.2 yi+1的位置选择yi-1=yi 或者yi+1=yi+1选择的原则是看精确值y与yi及yi+1的距离d1及d2的大小而定。

计算式为:y=m(xi+1)+b (2.1.1)d1=y-yi (2.1.2)d2=yi+1-y (2.1.3)如果d1-d2>0,则yi+1=yi+1,否则yi+1=yi。

因此算法的关键在于简便地求出d1-d2的符号。

将式(2.1.1)、(2.1.2)、(2.1.3)代入d1-d2,得用dx乘等式两边,并以Pi=dx(d1-d2)代入上述等式,得Pi=2xidy-2yidx+2dy+dx(2b-1) (2.1.4)d1-d2是我们用以判断符号的误差。

由于在1a象限,dx总大于0,所以Pi仍旧可以用作判断符号的误差。

Pi+1为:Pi+1=Pi+2dy-2dx(yi+1-yi) (2.1.5)误差的初值P1,可将x1, y1,和b代入式(2.1.4)中的xi, yi而得到:P1=2dy-dx综述上面的推导,第1a象限内的直线Bresenham算法思想如下:1、画点(x1, y2); dx=x2-x1; dy=y2-y1;计算误差初值P1=2dy-dx; i=1;2、求直线的下一点位置:xi+1=xi+1;if Pi>0 则yi+1=yi+1;否则yi+1=yi;3、画点(xi+1, yi-1);4、求下一个误差Pi+1;if Pi>0 则Pi+1=Pi+2dy-2dx;否则Pi+1=Pi+2dy;5、i=i+1; if i<dx+1则转2;否则end。

像素画圆算法范文

像素画圆算法范文

像素画圆算法范文一、引言像素画圆算法是一种用于计算机图形学中绘制圆的常用算法。

在计算机图形学中,圆是一个非常基本的图形元素,无论是在2D还是3D图形中,圆都是最直观的图形之一、因此,能够高效绘制圆形对于计算机图形学来说是非常重要的。

在本篇文章中,我们将介绍两种常用的像素画圆算法:Bresenham算法和中点画圆算法。

这两种算法都是基于直线绘制算法的思想发展而来,通过巧妙的数学推导,将直线绘制算法应用到圆形的绘制过程中。

二、Bresenham算法Bresenham算法是一种经典的像素画圆算法,它是由Jack E. Bresenham于1962年发明的。

该算法通过计算以像素为单位的数学判定来绘制圆形。

该算法的基本思想是,对于给定的圆心坐标和半径长度,我们从一个点开始,根据圆的对称性,计算出其他8个对称特殊点的坐标,并选择最接近圆的边缘的点绘制。

接着,根据选择的点计算下一个边缘点,并反复迭代这一过程,直到找到了整个圆的边缘点。

具体的Bresenham算法如下:1.初始化半径r和圆心坐标(x,y);2.设置两个变量x1和y1分别为0和r;3.计算判别式d=3-2*r;4.在每次迭代中,绘制八个对称点中最接近圆边缘的点,并更新判别式d和坐标x和y的值:-如果d<0,选择右偏移的点(x+1,y),d的值不变;-如果d>=0,选择右上偏移的点(x+1,y+1),d的值减去Δd;-更新判别式d=d+4*x+6;5.重复步骤4,直到x>y。

这里的Δd是一个关于x和y的常数,它的值预先计算得出,使得可以在循环中快速计算判别式d的变化。

通过这种方式,Bresenham算法能够高效地计算出整个圆的边缘点,从而实现圆形的绘制。

三、中点画圆算法中点画圆算法(Midpoint Circle Drawing Algorithm)是另一种常用的像素画圆算法,它是由Jack E. Bresenham于1977年发展而来的。

Bresenham快速画直线算法

Bresenham快速画直线算法

Bresenham快速画直线算法 现在的计算机的图像的都是⽤像素表⽰的,⽆论是点、直线、圆或其他图形最终都会以点的形式显⽰。

⼈们看到屏幕的直线只不过是模拟出来的,⼈眼不能分辨出来⽽已。

那么计算机是如何画直线的呢,其实有⽐较多的算法,这⾥讲的是Bresenham的算法,是光栅化的画直线算法。

直线光栅化是指⽤像素点来模拟直线,⽐如下图⽤蓝⾊的像素点来模拟红⾊的直线。

给定两个点起点P1(x1, y1), P2(x2, y2),如何画它们直连的直线呢,即是如何得到上图所⽰的蓝⾊的点。

假设直线的斜率0<k>0,直线在第⼀象限,Bresenham算法的过程如下:1.画起点(x1, y1).2.准备画下⼀个点,X坐标加1,判断如果达到终点,则完成。

否则找下⼀个点,由图可知要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点。

2.1.如果线段ax+by+c=0与x=x1+1的交点y坐标⼤于(y+*y+1))/2则选右上那个点 2.2.否则选右下那个点。

3.画点4.跳回第2步5.结束 算法的具体过程是怎样的呢,其实就是在每次画点的时候选取与实现直线的交点y坐标的差最⼩的那个点,例如下图:关键是如何找最近的点,每次x都递增1,y则增1或者不增1,由上图,假设已经画了d1点,那么接下来x加1,但是选d2 还是u点呢,直观上可以知道d2与⽬标直线和x+1直线的交点⽐较近即纵坐标之差⼩也即与(x+1, y+1)点纵坐标差⼤于0.5,所当然是选d2,其他点了是这个道理。

⼀、算法原理简介:算法原理的详细描述及部分实现可参考:假设以(x, y)为绘制起点,⼀般情况下的直观想法是先求m = dy /dx(即x每增加1, y的增量),然后逐步递增x, 设新的点为x1 = x + j,则y1 = round(y + j * m)。

可以看到,这个过程涉及⼤量的浮点运算,效率上是⽐较低的(特别是在嵌⼊式应⽤中,DSP可以⼀周期内完成2次乘法,⼀次浮点却要上百个周期)。

Bresenham画直线算法

Bresenham画直线算法

Bresenham画直线算法发表于:03-28 20:23 | 分类:代码阅读:(4) 评论:(0)给定两个点起点P1(x1, y1), P2(x2, y2),如何画它们直连的直线呢,即是如何得到上图所示的蓝色的点。

假设直线的斜率0<k>0,直线在第一象限,Bresenham算法的过程如下:1.画起点(x1, y1).2.准备画下一个点,X坐标加1,判断如果达到终点,则完成。

否则找下一个点,由图可知要画的点要么为当前点的右邻接点,要么是当前点的右上邻接点。

2.1.如果线段ax+by+c=0与x=x1+1的交点y坐标大于(y+*y+1))/2则选右上那个点2.2.否则选右下那个点。

3.画点4.跳回第2步5.结束具体的算法如下,原理就是比较目标直线与x+1直线交点的纵坐标,哪个离交点近就去哪个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 (x= x0;x < x1; x++){drawpixel(x, y, color);//这个是画点子函数e = e + k;if (e > 0){y++;e = e - 1;}}}上述Bresenham算法在计算直线斜率与误差项时用到小数与除法。

可以改用整数以避免除法。

等式两边同时乘以2*dx,得到2*e*dx = 2*e*dx + 2dy, 2*e*dx = 2*e*dx - 2*dx.由于算法中只用到误差项的符号,因此可作如下替换:2*e*dx.改进的Bresenham画线算法程序:将e统一乘以2*dx即变成了整数的Bresenhan算法了,^_^void InterBresenhamline (int x0, int y0, int x1, int y1, int color){int dx = x1 - x0;int dy = y1 - y0;int dx2 = dx << 1;//乘2int dy2 = dy << 1;//乘2int e = -dx;int x = x0;int y = y0;for (x = x0; x < x1; x++){drawpixel (x, y, color);e=e + dy2;if (e > 0){y++;e = e - dx2;}}}其他象限或斜率不同可以转换一下位置即可,这里不具体展开。

Bresenham算法

Bresenham算法

Bresenham算法1 算法原理基本原理从某处摘得:设直线⽅程为y i+1=y i+k(x i+1-x i)+k。

假设列坐标象素已经确定为x i,其⾏坐标为y i。

那么下⼀个象素的列坐标为x i+1,⽽⾏坐标要么为y i,要么递增1为y i+1。

是否增1取决于误差项d的值。

误差项d的初值d0=0,x坐标每增加1,d的值相应递增直线的斜率值k,即d=d+k。

⼀旦d≥1,就把它减去1,这样保证d在0、1之间。

当d≥0.5时,直线与垂线x=x i+1交点最接近于当前象素(x i,y i)的右上⽅象素(x i+1,y i+1);⽽当d<0.5时,更接近于右⽅象素(x i+1,y i)。

为⽅便计算,令e=d-0.5,e的初值为-0.5,增量为k。

当e≥0时,取当前象素(x i,y i)的右上⽅象素(x i+1,y i+1);⽽当e<0时,取(x i,y i)右⽅象素(x i+1,y i)。

由于显⽰直线的像素点只能取整数值坐标,可以假设直线上第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。

d1 = Y - Y i = m(X i+1)+b - Y i; (1) d2 = (Y i+1) - Y = (Y i+1) - m(X i+1) - b; (2) 两个距离的差是: d1-d2 = 2m(X i+1) - 2Y i + 2b -1; (3) 对于公式(3): a:当此值为正时,d1>d2,说明直线上理论点离(X i+1,Y i+1)像素较近,下⼀个像素点应取(X i+1,Y i+1); b:当此值为负时,d1<d2,说明直线上理论点离(X i+1,Y i)像素较近,下⼀个像素点赢取(X i+1,Y i); c:当此值为零时,d1=d2,说明直线上理论点离上、下两个像素点的距离相等,取那个点都⾏,假设算法规定这种情况下取(X i+1,Y i+1)作为下⼀个像素点。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程实验报告步骤为了规范颜色的处事,定义了CRGB类,重载了“+”,“-”、“*”、“\”、“+=”、“-=”、“*=”、“/=”运算符。

成员函数Normalize()将颜色分量red,green,blue规范到[0,1]闭区间内。

RGB.h#pragma onceclass CRGB{public:CRGB();CRGB(double, double, double);~CRGB();friend CRGB operator + (const CRGB&, const CRGB&);friend CRGB operator - (const CRGB&, const CRGB&);friend CRGB operator * (const CRGB&, const CRGB&);friend CRGB operator * (const CRGB&, double);friend CRGB operator * (double, const CRGB&);friend CRGB operator / (const CRGB&, double);friend CRGB operator += (const CRGB&, const CRGB&);friend CRGB operator -= (const CRGB&, const CRGB&);friend CRGB operator *= (const CRGB&, const CRGB&);friend CRGB operator /= (const CRGB&, double);void Normalize();public:double red;double green;double blue;};RGB.cpp#include"stdafx.h"#include"RGB.h"CRGB::CRGB(){red = 1.0;green = 1.0;blue = 1.0;}CRGB::~CRGB(){}CRGB::CRGB(double r, double g, double b){red = r;green = g;blue = b;}CRGB operator +(const CRGB &c1, const CRGB &c2) {CRGB c;c.red = c1.red + c2.red;c.green = c1.green + c2.green;c.blue = c1.blue + c2.blue;return c;}CRGB operator - (const CRGB &c1, const CRGB &c2) {CRGB c;c.red = c1.red - c2.red;c.green = c1.green - c2.green;c.blue = c1.blue - c2.blue;return c;}CRGB operator * (const CRGB&c1, const CRGB&c2) {CRGB c;c.red = c1.red * c2.red;c.green = c1.green * c2.green;c.blue = c1.blue * c2.blue;return c;}CRGB operator * (const CRGB&c1, double k){CRGB c;c.red = c1.red*k;c.green = c1.green*k;c.blue = c1.blue*k;return c;}CRGB operator * (double k, const CRGB&c1){CRGB c;c.red = c1.red*k;c.green = c1.green*k;c.blue = c1.blue*k;return c;}CRGB operator / (double k, const CRGB&c1){CRGB c;c.red = c1.red / k;c.green = c1.green / k;c.blue = c1.blue / k;return c;}CRGB operator +=(const CRGB &c1, const CRGB &c2) {CRGB c;c.red = c1.red + c2.red;c.green = c1.green + c2.green;c.blue = c1.blue + c2.blue;return c;}CRGB operator -= (const CRGB &c1, const CRGB &c2) {CRGB c;c.red = c1.red - c2.red;c.green = c1.green - c2.green;c.blue = c1.blue - c2.blue;return c;}CRGB operator *= (const CRGB&c1, const CRGB&c2) {CRGB c;c.red = c1.red * c2.red;c.green = c1.green * c2.green;c.blue = c1.blue * c2.blue;return c;}CRGB operator /= (const CRGB&c1, double k){CRGB c;c.red = c1.red / k;c.green = c1.green / k;c.blue = c1.blue / k;return c;}void CRGB::Normalize(){red = (red<0.0) ? 0.0 : ((red>1.0) ? 1.0 : red);green = (green<0.0) ? 0.0 : ((green>1.0) ? 1.0 : green);blue = (blue<0.0) ? 0.0 : ((blue>1.0) ? 1.0 : blue);}4、设计Cline直线类定义直线绘制任意斜率的直线,其成员函数为MoveTo()和LineTo()。

Line.h#pragma once#include"P2.h"#include"RGB.h"class CLine{public:CLine();virtual ~CLine();void MoveTo(CDC *, CP2);//移动到指定位置void MoveTo(CDC *, double, double);void LineTo(CDC *, CP2);//绘制直线,不含终点void LineTo(CDC *, double, double);public:CP2P0;//起点CP2P1;//终点};Line.cpp#include"stdafx.h"#include"Line.h"#include"math.h"#define Round(d) int(floor(d+0.5))//四舍五入宏定义#ifdef_DEBUG#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#define new DEBUG_NEW#endifCLine::CLine(){}CLine::~CLine(){}void CLine::MoveTo(CDC *pDC, CP2p0)//绘制直线起点函数{P0 = p0;}void CLine::MoveTo(CDC *pDC, double x0, double y0)//重载函数{P0 = CP2(x0, y0);}void CLine::LineTo(CDC *pDC, CP2p1){P1 = p1;CP2p, 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;}elsed += 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;}elsed -= 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;}elsed -= 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;}elsed -= 1;}}}P0 = p1;}void CLine::LineTo(CDC *pDC, double x1, double y1)//重载函数{LineTo(pDC, CP2(x1, y1));}5、添加鼠标消息映射添加WM_LBUTTONDOWN消息映射函数void CTestView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值p0.x = point.x;p0.y = point.y;p0.x = p0.x - rect.Width() / 2; //设备坐标系向自定义坐标系转换p0.y = rect.Height() / 2 - p0.y;CView::OnLButtonDown(nFlags, point);}添加WM_LBUTTONUP消息映射函数void CTestView::OnLButtonUp(UINT nFlags, CPoint point){// TODO: 在此添加消息处理程序代码和/或调用默认值p1.x=point.x;p1.y=point.y;CLine *line=new CLine;CDC *pDC=GetDC();//定义设备上下文指针//与案例比新加的语句GetClientRect(rect);pDC->SetMapMode(MM_ANISOTROPIC); //自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height()); //设置窗口比例pDC->SetViewportExt(rect.Width(),-rect.Height()); //设置视区比例,且x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//设置客户区中心为坐标系原点rect.OffsetRect(-rect.Width()/2,-rect.Height()/2); //矩形与客户区重合/*pDC->MoveTo(0, 0);pDC->LineTo(100, 200);*/p1.x=p1.x-rect.Width()/2;p1.y=rect.Height()/2-p1.y;line->MoveTo(pDC,p0);line->LineTo(pDC,p1);delete line;ReleaseDC(pDC);CView::OnLButtonUp(nFlags, point);}调试过程及实验结果总结本案例实现的Cline类的成员函数类似于CDC类的MoveTo()函数和LineTo()函数,用于绘制任意斜的直线段。

相关文档
最新文档