计算机图形学-设计算法绘制直线与圆
- 格式:doc
- 大小:754.00 KB
- 文档页数:32
实验一、直线的生成实验目的:1、掌握DDA直线画法、中点画线法和Bresenham画线法2、掌握VC++简单程序设计方法实验内容:根据提供的程序框架,修改部分代码,完成画一条直线的功能(中点画线法或者Bresenham画线法任选一),只要求实现在第一象限内的直线。
实验步骤和方法:首先启动Visual C++ 6.0(注意,其它版本程序无法正确编译),文件(file)→打开工作空间(open workspace)。
打开实验12用基本图形生成\基本图形生成.dsw。
在fileview窗口,source file下,双击直线生成view.cpp,或者classview窗口下,cmyview类下相应的函数,按注释改写下列函数:void CMyView::OnDdaline() (此为DDA生成直线)void CMyView::OnBresenhamline()(此为Bresenham画直线)void CMYView::OnMidPointLine()(此为中点画线法)程序代码说明:1、直线的两个端点,由对话框输入,给定程序已经完成输入代码。
2、SetPixel的用法:COLORREF SetPixel(int x, int y, COLORREF crColor);//x,y为坐标点。
COLORREF SetPixel(POINT point, COLORREF crColor);//point为坐标点。
3、本实验事先提供DDA话直线的函数示范(红色部分是重点,其它部分可以不看)中点画直线函数和BresenHam画直线函数由同学们参照dda直线的示例函数自己完成。
//以下为DDA画直线的源程序float x,y,dx,dy,k;dx=(float)(xb-xa);dy=(float)(yb-ya);k=dy/dx;x=xa;y=ya;if(abs(k)<1){for (x=xa;x<=xb;x++){pdc->SetPixel(x, int(y+0.5),COLOR);y=y+k;}}if(abs(k)>=1){for(y=ya;y<=yb;y++){pdc->SetPixel(int(x+0.5),y,COLOR);x=x+1/k;}}//DDA画直线结束//以下为中点画直线的源程序float a,b,d1,d2,d,x,y;a=ya-yb,b=xb-xa,d=2*a+b;d1=2*a,d2=2*(a+b);x=xa,y=ya;pdc->SetPixel(x,y,COLOR);while(x<xb){ if(d<0){x++,y++,d+=d2;}else {x++,d+=d1;}pdc->SetPixel(x,y,COLOR);}//中点画直线结束//以下为Bresenham画直线的源程序int i,s1,s2,interchange;float f,x,y,deltax,deltay,temp; x=xa;y=ya;deltax=abs(xb-xa);deltay=abs(yb-ya);if(xb-xa>=0)s1=1;else s1=-1;if(yb-ya>=0)s2=1;else s2=-1;if(deltay>deltax){ temp=deltax;deltax=deltay;deltay=temp;interchange=1;}else interchange=0;f=2*deltay-deltax;pdc->SetPixel(x,y,COLOR);for(i=1;i<=deltax;i++){ if(f>=0){if(interchange==1) x+=s1;else y+=s2;pdc->SetPixel(x,y,COLOR);f=f-2*deltax;}else {if(interchange==1) y+=s2;else x+=s1;f=f+2*deltay;}}}//Bresenham画直线结束实验二、圆的生成(中点和Bresenham法)实验目的:1、掌握bresenham画圆的算法。
计算机科学与技术学院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)。
这时可以把改点带入所在直线方程,可以观察该中点与直线的位置关系。
第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表示像素的颜色和灰度。
第3章直线和圆弧的生成算法3.1直线图形的生成算法数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。
当我们对直线进展光栅化时,需要在显示器有限个像素中,确定最优逼近该直线的一组像素,并且按扫描线顺序,对这些像素进展写操作,这个过程称为用显示器绘制直线或直线的扫描转换。
由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。
本节我们介绍一个像素宽直线绘制的三个常用算法:数值微分法〔DDA〕、中点画线法和Bresenham算法。
3.1.1逐点比拟法3.1.2数值微分(DDA)法设过端点P0(x0,y0)、P1(x1,y1)的直线段为L(P0,P1),如此直线段L的斜率L的起点P0的横坐标x0向L的终点P1的横坐标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 DDALine(int x0,int y0,int x1,int y1,int color){ int x;float dx, dy, y, k;dx = x1-x0;dy=y1-y0;k=dy/dx,;y=y0;for (x=x0;x< x1;x++){ drawpixel (x, int(y+0.5), color);y=y+k;}}注意:我们这里用整型变量color表示像素的颜色和灰度。
举例:用DDA方法扫描转换连接两点P0〔0,0〕和P1〔5,2〕的直线段。
x int(y+0.5) y0 0 01 02 13 14 2图3 直线段的扫描转换注意:上述分析的算法仅适用于|k| ≤1的情形。
计算机图形学课程设计报告课题名称直线和圆中点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。
信息与计算科学专业基础课ComputerReport Of course 计算机图形学课程实验报告实验题目设计算法绘制直线与圆班级姓名学号指导教师日期实验说明 试验目的: 掌握直线和圆的基本生成算法思想,并上机编程实现相应的算法。
试验地点: 教九楼401 数学系机房实验要求(Direction): 1. 每个学生单独完成;2.开发语言为TurboC 或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。
实验内容实验题一实验题目1).用DDA 法在屏幕上画一条具有三个像素宽的直线段L1。
要求:(1)直线段L1的两个端点坐标和画线颜色都要求可以随机输入;(2)要求输出直线段L1上的各点坐标;(3)画出直线的同时要求标明两端点坐标。
2).将课堂所讲的斜率0<K<1的中点画线算法推广到斜率K>1、-1<K<0和K<-1的情况,编写一通用的中点画线算法。
实验目的和意义1.了解如何利用C 语言和图形函数进行绘图;2. 熟悉并掌握C 语言的图形模式控制函数,图形屏幕操作函数,以及基本图形函数;3. 通过对Turbo C 进行图形程序设计的基本方法的学习,能绘制出简单的图形;4. 熟悉并掌握DDA 法在屏幕上画一条具有三个像素宽的直线段L1以及通用的中点画线算法。
通过DDA 法及用的中点画线算法,了解图形系统初始化、图形系统关闭和图设计算法绘制直线与圆实验2形模式的控制,并熟练运用图形坐标的设置,包括定点、读取光标以及图形颜色的设置。
程序制作步骤(包括算法思想、算法流程图等)1.自动搜索显示器类型和显示模式,初始化图形系统,通过printf 、scanf 语句控制线段的端点坐标和画线颜色的自由输入;2. DDAline:设直线之起点为(x1,y1),终点为(x2,y2),则斜率k 为: 则有:⑴.可通过计算由x 方向的增量x ∆引起y 的改变生成直线。
由1i i y y y +=+∆ (i y 为直线上某步的初值)则21121i i i y y y y x y k x x x +-=+∆=+∆- ⑵.也可通过计算由y 方向的增量y ∆引起x 的改变生成直线。
由1i i x x x +=+∆(i x 为直线上某步的初值)则:211211i i i x x x x y x y y y k+-=+∆=+∆- :⑴.假定X 坐标为p x 的各像素点中,与直线最近点已确定为(,)p p x y (用实心小圆表示),那么下一个与直线最近的象素点只能是正右方的1(1,)p p p x y +或右上方2(1,1)p p p x y ++两者之一。
⑵. 再以M 表示P1与P2的中点,即(1,0.5)p p M x y =++又设Q 是理想直线与垂直线1p x x =+的交点 。
显然有:①.当M 在Q 的下方,则P2 离直线 近,应取为下一个象素点;②.当M 在Q 的上方,则P1离直线 近,应取为下一个象素点。
③.当M 和Q 重合,则P 1和P2离直线 一样近,两者均可取为下一个象素点主程序xyx x y y k ∆∆=--=12121+=p x xDDA算法#include ""#include <>#include <>#include <>#include <>DDAline(int x1, int y1, int x2, int y2, int c) {float delta_x = 0;float delta_y = 0;float x = 0;float y = 0;int dx= 0;int dy = 0;int steps = 0;int k = 0;dx=x2-x1;dy=y2-y1;if (abs(dx)>abs(dy)){steps=3*abs(dx);}else{steps=3*abs (dy);}delta_x=(float)dx / (float)steps;delta_y=(float)dy / (float)steps;x=float(x1);y=float(y1);for (k=1; k<=steps;k++){putpixel(int(x+, int(y+, c);x+=delta_x;y+=delta_y;}return 0;}void main(){char t[100] = {0};int x1 = 0;int y1 = 0;int x2 = 0;int y2 = 0;int c = 0;void dda_line(int x1,int y1,int x2,int y2,int c);int graphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,"D:\\TC"); /*初始化图形系统*/printf("输入两端点坐标:\n");scanf("<%d,%d>,<%d,%d>",&x1,&y1,&x2,&y2);printf("输入画线颜色:\n");scanf("%d",&c);DDAline(x1,y1,x2,y2,c);sprintf(t,"(%d,%d)",x1,y1);outtextxy(x1,y1,t);sprintf(t,"(%d,%d)",x2,y2);outtextxy(x2,y2,t);getch(); /*等待按一键结束*/closegraph(); /*关闭图形系统,回到文本模式*/ }中点画线算法#include <>#include <>#include <>#include <>#include ""MidpointLine(int x1,int y1,int x2,int y2,int c){int a = 0;int b = 0;int d1 = 0;int d2 = 0;int d = 0;int x = 0;int y = 0;float m = 0;if (x2<x1){d=x1;x1=x2;x2=d;d=y1;y1=y2;y2=d;}a=y1-y2;b=x2-x1;if (b==0){m=-1*a*100;}else{m=(a/(x1-x2)); }x=x1;y=y1;putpixel(x,y,c);if (m>=0 && m<=1){d=2*a+b;d1=2*a;d2=2*(a+b);while (x<x2){if (d<=0){x++;y++;d+=d2;}else{x++;d+=d1;}putpixel(x,y,c);}}else if (m<=0 && m>=-1){d=2*a-b;d1=2*a-2*b;d2=2*a;while (x<x2){if (d>0){x++;y--;d+=d1;}else{x++;d+=d2;}putpixel(x,y,c);}}else if (m>1){d=a+2*b;d1=2*(a+b);d2=2*b;while (y<y1){if (d>0){x++;y++;d+=d1;}else{y++;d+=d2;}putpixel(x,y,c);}}else{d=a-2*b;d1=-2*b;d2=2*(a-b);while (y>y1){if (d<=0){x++;y--;d+=d2;}else{y--;d+=d1;}putpixel(x,y,c);}}return 0;}void main(){char t[100] = {0};int x1 = 0;int y1 = 0;int x2 = 0;int y2 = 0;int c = 0;int graphdriver=DETECT,graphmode;initgraph(&graphdriver,&graphmode,"D:\\TC"); /*初始化图形系统*/printf("输入两端点坐标:\n");scanf("<%d,%d>,<%d,%d>",&x1,&y1,&x2,&y2);printf("输入画线颜色:\n");scanf("%d",&c);MidpointLine(x1,y1,x2,y2,c);sprintf(t,"(%d,%d)",x1,y1);outtextxy(x1,y1,t);sprintf(t,"(%d,%d)",x2,y2);outtextxy(x2,y2,t);getch(); /*等待按一键结束*/closegraph(); /*关闭图形系统,回到文本模式*/ }运行结果图DDA算法图算法运行结果截图图算法运行结果截图中点画线算法图中点画线算法当k<=1时运行结果截图图中点画线算法当k<=1时运行结果截图图中点画线算法当0<k<1时运行结果截图图中点画线算法当0<k<1时运行结果截图图中点画线算法当k=-1时运行结果截图图中点画线算法当k=-1时运行结果截图图中点画线算法当-1<k<0时运行结果截图图中点画线算法当-1<k<0时运行结果截图图中点画线算法当k<-1时运行结果截图实验题二实验题目1).参考课堂所讲过的斜率为0~1和大于1的Bresenham画线程序,将该算法程序扩展到任一八分圆坐标空间图,从而形成一般的Bresenham画线算法。
并利用Bresenham画线算法画出4条不同颜色、不同斜率的直线段L1、L2、L3、L4。
要求:(1)4条直线段L1、L2、L3、L4的斜率K1、K2、K3、K4满足:0<K1<1,-1<K2<0, K3<-1,K4>1;(2)直线段的两个端点坐标和画线颜色都要求可以随机输入。