计算机图形学实验三
- 格式:docx
- 大小:60.86 KB
- 文档页数:6
计算机图形学实验03
《计算机图形学》实验报告
圆(椭圆)的生成算法
一、实验教学目标与基本要求
1.实现圆的生成算法;
2.实现椭圆的生成算法;
二、实验课程内容 (2学时)
1.写出完整的圆的Bresenham生成算法;
2.写出完整的椭圆的中点生成算法;
三、算法思想
1.圆的Bresenham生成算法:
如果我们构造函数 F(_,y)=_+y-R,则对于圆上的点有F(_,y)=0,对于圆外的点有F(_,y)_gt;0,对于圆内的点F(_,y)_lt;0 。
与中点画线法一样,构造判别式:d=F(M)=F(_p+1,yp-0.5)=(_p+1)+(yp-0.5)-R。
若d_lt;0,则应取P1为下一象素,而且再下一象素的判别式为:
222d=F(_p+2,yp-0.5)=(_p+2)+(yp-0.5)-R=d+2_p+3
若d≥0,则应取P2为下一象素,而且下一象素的判别式为:
d=F(_p+2,yp-1.5)=(_p+2)+(yp-
1.5)-R=d+2(_p-yp)+5我们这里讨论的第一个象素是(0,R),判别式d的初始值为:d0=F(1,R-0.5)=1.25-R。
为了进一步提高算法的效率,将上面的算法中的浮点数改写成整数,将乘法运算改成加法运算,即仅用整数实现中点画圆法。
2.椭圆的中点生成算法:
椭圆中点生成算法是将椭圆在第一象限中分为两个部分:
1)对于斜率绝对值小于1的区域内在_方向取单位量;
2)对于斜率绝对值大于1的区域内在y方向取单位量;
斜率可以通过椭圆的标准方程中获得为K = - (ry_ry)__/(r__r_)_y;这里中点椭圆222222222。
计算机图形学实验指导书袁科计算机技术实验中心目录实验一实现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 曲线的绘制与显示。
实验报告模板《计算机图形学》实验报告一、实验目的及要求1.实习三维图形的坐标系之间的变换;2.三维图形几何变换;3.掌握三维图形的坐标系之间的变换算法及三维图形几何变换的原理和实现;4.实现二维图形的基本变换(平移、旋转、缩放、错切、对称、复合等);5.实现三维图形的基本变换(平移、旋转、缩放、复合等);二、理论基础在齐次坐标理论下,二维图形几何变换矩阵可用下式表示:⎪⎪⎪⎭⎫⎝⎛===ifchebgdaTnkxx kk2,1,0,)(ϕ平移变换:[x* y* 1] =[x y 1] *0000001ts⎛⎫⎪⎪⎪⎝⎭=[t*x s*y 1]比例变换:[x* y* 1]=[x y 1] *1000101m n⎛⎫⎪⎪⎪⎝⎭=[m+x n+y 1]旋转变换:在平面上的二维图形饶原点逆时针旋转Ө角,变换矩阵为[x* y* 1]=[x y 1] *cos sin0sin cos0001θθθθ⎛⎫⎪- ⎪⎪⎝⎭= [x*cosө-y*sinө]复合变换:以上各种变换矩阵都是以原点为参照点,当以任意参照点进行变换的时候,我们就要用到复合变换矩阵。
三维变换类似于二维,在画图时,把三维坐标转换为二维即可。
三、算法设计与分析二维变换:#define dx 50#define dy 100void CCGWithVCView::OnTransScale() //平移(50,100){// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Move Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]+dx;a[1]=m[i][1]+dy;b[0]=m[i+1][0]+dx;b[1]=m[i+1][1]+dy;DDALine(a,b, RGB(0, 200, 255), pDC);}}#define h 0.1745#include<math.h>void CCGWithVCView::OnTransRotate() //旋转{// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Rotate Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]*cos(h)-m[i][1]*sin(h);a[1]=m[i][1]*cos(h)+m[i][0]*sin(h);b[0]=m[i+1][0]*cos(h)-m[i+1][1]*sin(h);b[1]=m[i+1][1]*cos(h)+m[i+1][0]*sin(h);DDALine(a,b, RGB(0, 200, 255), pDC);}}#define k 2;#define f 2.5void CCGWithVCView::OnTransMove() //缩放{// TODO: Add your command handler code here//AfxMessageBox(_T("Please Insert The Scale Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]*k;a[1]=m[i][1]*f;b[0]=m[i+1][0]*k;b[1]=m[i+1][1]*f;DDALine(a,b, RGB(0, 200, 255), pDC);}}#define n 2#define d 0void CCGWithVCView::OnTransOther(){// TODO: Add your command handler code here//AfxMessageBox(_T("Please Insert The Other Change Code!")) ;int m[4][2]={{100,50},{50,100},{150,100},{100,50}};int i;int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<3;i++){a[0]=m[i][0];a[1]=m[i][1];b[0]=m[i+1][0];b[1]=m[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for(i=0;i<3;i++){a[0]=m[i][0]+n*m[i][1];a[1]=m[i][1]+d*m[i][0];b[0]=m[i+1][0]+n*m[i+1][1];b[1]=m[i+1][1]+d*m[i+1][0];DDALine(a,b, RGB(0, 200, 255), pDC);}}三维变换:#include<math.h>#define dx 100#define dy 100#define dz 0void CCGWithVCView::OnTransScale() //平移(50,100){// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Move Change Code!")) ;int i;int p2d[6][2];int p3d[6][3]={{400,300,0},{300,400,0},{300,300,10},{275,300,0},{400,300,0},{300,300,10}};for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]+p3d[i][0]/sqrt(2);}int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]+dy-p3d[i][0]+dx/sqrt(2);p2d[i][1]=p3d[i][2]+dz+p3d[i][0]+dx/sqrt(2);}for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 0, 255), pDC);}}#define k 0.1745void CCGWithVCView::OnTransRotate() //旋转{// TODO: Add your command handler code here// AfxMessageBox(_T("Please Insert The Rotate Change Code!")) ;int i;int p2d[6][2];int p3d[6][3]={{400,300,0},{300,400,0},{300,300,10},{275,300,0},{400,300,0},{300,300,10}};for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]+p3d[i][0]/sqrt(2);}int a[2],b[2];CDC * pDC = GetDC();for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 200, 255), pDC);}for( i=0;i<6;i++){p2d[i][0]=p3d[i][1]*cos(k)-p3d[i][2]*sin(k)-p3d[i][0]/sqrt(2);p2d[i][1]=p3d[i][2]*cos(k)+p3d[i][1]*sin(k)+p3d[i][0]/sqrt(2);}for(i=0;i<5;i++){a[0]=p2d[i][0];a[1]=p2d[i][1];b[0]=p2d[i+1][0];b[1]=p2d[i+1][1];DDALine(a,b, RGB(0, 0, 255), pDC);}}四、程序调试及结果的分析二维:三维:五、实验心得及建议在实验过程中,尽管过程中任由许多不会的地方,而且有待于今后的提高和改进,但我加深了对书本上知识的理解与掌握,同时也学到了很多书本上没有东西,并积累了一些宝贵的经验,这对我以后的学习与工作是不无裨益的。
图形学实验报告图形学实验报告概述:在本次图形学实验中,我们将探索和学习计算机图形学的基本概念和技术。
通过实验,我们深入了解了图形学的原理和应用,以及如何使用计算机生成和处理图像。
实验一:像素和颜色在这个实验中,我们学习了图像是由像素组成的,每个像素都有自己的颜色值。
我们使用了Python编程语言和PIL库来创建一个简单的图像,并设置了不同的像素颜色。
通过改变像素的颜色值,我们可以创建出各种各样的图像效果。
实验二:坐标系统和变换在这个实验中,我们学习了坐标系统和图形变换。
我们使用OpenGL库来创建一个简单的二维图形,并通过平移、旋转和缩放等变换操作来改变图形的位置和形状。
这些变换操作使我们能够在屏幕上创建出各种不同的图案和效果。
实验三:线段和多边形在这个实验中,我们学习了如何使用线段和多边形来绘制图形。
我们使用了Bresenham算法来绘制直线,并学习了如何使用多边形填充算法来填充图形。
通过这些技术,我们可以创建出更加复杂和精细的图像。
实验四:光照和阴影在这个实验中,我们学习了光照和阴影的原理和应用。
我们使用了光照模型来模拟光线的传播和反射,以及计算物体的明暗效果。
通过调整光照参数和材质属性,我们可以创建出逼真的光照和阴影效果。
实验五:纹理映射和渲染在这个实验中,我们学习了纹理映射和渲染的概念和技术。
我们使用了纹理映射来将图像贴到三维物体表面,以增加物体的细节和真实感。
通过渲染技术,我们可以模拟光线的折射和反射,以及创建出逼真的材质效果。
实验六:三维建模和动画在这个实验中,我们学习了三维建模和动画的基本原理和方法。
我们使用了三维建模工具来创建三维模型,并学习了如何使用关键帧动画来实现物体的运动和变形。
通过这些技术,我们可以创建出逼真的三维场景和动画效果。
总结:通过这次图形学实验,我们深入了解了计算机图形学的原理和应用。
我们学习了像素和颜色、坐标系统和变换、线段和多边形、光照和阴影、纹理映射和渲染,以及三维建模和动画等技术。
《计算机图形学》实验报告一、实验目的计算机图形学是一门研究如何利用计算机生成、处理和显示图形的学科。
通过本次实验,旨在深入理解计算机图形学的基本原理和算法,掌握图形的生成、变换、渲染等技术,并能够运用所学知识解决实际问题,提高对图形学的应用能力和编程实践能力。
二、实验环境本次实验使用的编程语言为 Python,使用的图形库为 Pygame。
开发环境为 PyCharm。
三、实验内容1、直线的生成算法DDA 算法(Digital Differential Analyzer)Bresenham 算法DDA 算法是通过计算直线的斜率来确定每个像素点的位置。
它的基本思想是根据直线的斜率和起始点的坐标,逐步计算出直线上的每个像素点的坐标。
Bresenham 算法则是一种基于误差的直线生成算法。
它通过比较误差值来决定下一个像素点的位置,从而减少了计算量,提高了效率。
在实验中,我们分别实现了这两种算法,并比较了它们的性能和效果。
2、圆的生成算法中点画圆算法中点画圆算法的核心思想是通过判断中点的位置来确定圆上的像素点。
通过不断迭代计算中点的位置,逐步生成整个圆。
在实现过程中,需要注意边界条件的处理和误差的计算。
3、图形的变换平移变换旋转变换缩放变换平移变换是将图形在平面上沿着指定的方向移动一定的距离。
旋转变换是围绕一个中心点将图形旋转一定的角度。
缩放变换则是改变图形的大小。
通过矩阵运算来实现这些变换,可以方便地对图形进行各种操作。
4、图形的填充种子填充算法扫描线填充算法种子填充算法是从指定的种子点开始,将相邻的具有相同颜色或属性的像素点填充为指定的颜色。
扫描线填充算法则是通过扫描图形的每一行,确定需要填充的区间,然后进行填充。
在实验中,我们对不同形状的图形进行了填充,并比较了两种算法的适用情况。
四、实验步骤1、直线生成算法的实现定义直线的起点和终点坐标。
根据所选的算法(DDA 或Bresenham)计算直线上的像素点坐标。
计算机图形学基础实验报告院系:计算机科学学院班级:2012级4班姓名:彭晓学号:21209010434实验二直线生成算法的实现1.实验目的:理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL 实现直线光栅化的DDA算法。
2.实验内容:(1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;(2)指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告;(4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。
3.实验原理:示范代码原理参见教材直线光栅化一节中的DDA算法。
下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。
(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。
同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。
可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。
这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。
前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?是一个一个的画出来,还是连成线?或者构成一个多边形?或是做其它事情呢?为了解决这一问题,OpenGL要求:指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。
例如:glBegin(GL_POINTS);glVertex2f(0.0f, 0.0f);glVertex2f(0.5f, 0.0f);glEnd();则这两个点将分别被画出来。
如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。
还可以指定更多的顶点,然后画出更复杂的图形。
实验三:圆的生成算法的实现班级 08信计学号 20080502069 姓名分数一、实验目的和要求1、理解圆的基本原理。
2、掌握几种常见的圆生成算法。
3、利用TurboC实现圆生成的中点画圆算法。
4、理解圆生成的基本原理,掌握几种常见的圆生成算法。
5、利用Visual C++ 实现圆生成的中点画圆的算法。
6、利用Visual C++ 实现圆的Bresenham算法。
7、简单了解其他算法。
二、实验内容:1.利用中点画图算法,在屏幕上生成任意一段圆弧。
2.利用图的对称性,将(1)题生成的圆弧扩展为一个整圆。
3.利用bresebham算法设计出一段圆弧。
三、实验步骤:1.预习教材关于圆的生成原理。
2.仿照教材关于圆生成的中点画圆算法和bresenham算法,使用C++实现该算法。
3.调试、编译、运行程序。
四、实验结果分析:1.这里用圆生成的中点画圆算法为例来绘制一个圆。
程序代码:#include<graphics.h>#include<conio.h>void circlepoints(int x,int y,int color){int m,n;float xasp,yasp;float aspectratio;m=200;n=200;getaspectratio(&xasp,&yasp);aspectratio = xasp/yasp;putpixel(x+m,y*aspectratio+n,color);putpixel(y+m,x*aspectratio+n,color);putpixel(-y+m,x*aspectratio+n,color);putpixel(-x+m,y*aspectratio+n,color);putpixel(y+m,-x*aspectratio+n,color);putpixel(x+m,-y*aspectratio+n,color);putpixel(-x+m,-y*aspectratio+n,color);putpixel(-y+m,-x*aspectratio+n,color); }void midpointcircle(int r,int c){int x,y;float d;x=0; y=r; d=5.0/4-r;circlepoints(x,y,c);while(y>x){if(d<=0)d+=2.0*x+3;else{d+=2.0*(x-y)+5;y--;}x++;circlepoints(x,y,c);}}void main(){int a,b;int graphdriver = DETECT;int graphmode = 0;initgraph(&graphdriver,&graphmode,"");cleardevice();a= 200; b= 200;midpointcircle(a,b);getch();closegraph();}运行结果:2.利用bresenham算法生成圆的代码:#include<graphics.h>#include<stdio.h>#include<conio.h>void BresenhemCircle(int centerx, int centery, int radius, int color, int type);void main(){int drive=DETECT,mode;int i,j;initgraph(&drive,&mode,"");BresenhemCircle(300,200,100,150,0);getch();closegraph();}void BresenhemCircle(int centerx, int centery, int radius, int color, int type){int x =type = 0;/*初始横坐标为原点*/int y = radius; /*初始纵坐标远离原点*/int delta = 2*(1-radius);int direction;while (y >= 0){getch();if (!type)/*执行*/{/*在上半圆画两点*/putpixel(centerx+x, centery+y, color);putpixel(centerx-x, centery+y, color);/*在下半圆画两点*/putpixel(centerx-x, centery-y, color);putpixel(centerx+x, centery-y, color);getch();}else{line(centerx+x, centery+y, centerx+x, centery-y); line(centerx-x, centery+y, centerx-x, centery-y); getch();}if (delta < 0){if ((2*(delta+y)-1) < 0)direction = 1;elsedirection = 2;}else if(delta > 0){if ((2*(delta-x)-1) > 0)direction = 3;elsedirection = 2;}elsedirection=2;switch(direction){case 1:x++;delta += (2*x+1); break;case 2:x++;y--;delta += 2*(x-y+1); break;case 3:y--;delta += (-2*y+1); break;}}}实验结果:。
计算机图形学实验报告计算机图形学实验报告引言计算机图形学是研究计算机生成和处理图像的学科,它在现代科技和娱乐产业中扮演着重要的角色。
本实验报告旨在总结和分享我在计算机图形学实验中的经验和收获。
一、实验背景计算机图形学实验是计算机科学与技术专业的一门重要课程,通过实践操作和编程,学生可以深入了解图形学的基本原理和算法。
本次实验主要涉及三维图形的建模、渲染和动画。
二、实验内容1. 三维图形建模在实验中,我们学习了三维图形的表示和建模方法。
通过使用OpenGL或其他图形库,我们可以创建基本的几何体,如立方体、球体和圆柱体,并进行变换操作,如平移、旋转和缩放。
这些基本操作为后续的图形处理和渲染打下了基础。
2. 光照和着色光照和着色是图形学中重要的概念。
我们学习了不同的光照模型,如环境光、漫反射和镜面反射,并了解了如何在三维场景中模拟光照效果。
通过设置材质属性和光源参数,我们可以实现逼真的光照效果,使物体看起来更加真实。
3. 纹理映射纹理映射是一种将二维图像映射到三维物体表面的技术。
通过将纹理图像与物体的顶点坐标相对应,我们可以实现更加细致的渲染效果。
在实验中,我们学习了纹理坐标的计算和纹理映射的应用,使物体表面呈现出具有纹理和细节的效果。
4. 动画和交互动画和交互是计算机图形学的重要应用领域。
在实验中,我们学习了基本的动画原理和算法,如关键帧动画和插值技术。
通过设置动画参数和交互控制,我们可以实现物体的平滑移动和变形效果,提升用户体验。
三、实验过程在实验过程中,我们首先熟悉了图形库的使用和基本的编程技巧。
然后,我们按照实验指导书的要求,逐步完成了三维图形建模、光照和着色、纹理映射以及动画和交互等任务。
在实验过程中,我们遇到了许多挑战和问题,但通过不断的尝试和调试,最终成功实现了预期的效果。
四、实验结果通过实验,我们成功实现了三维图形的建模、渲染和动画效果。
我们可以通过键盘和鼠标控制物体的移动和变形,同时观察到真实的光照效果和纹理映射效果。
实验三圆的生成算法的实现班级 08信计学号 60姓名段丹丹分数一、实验目的与要求1. 掌握Bresenham画圆算法的基本思想。
2. 编写Bresenham算法画圆的基本函数并尽量完善。
3、熟悉圆的生成算法,掌握圆的绘制,利用TurboC来实现圆的生成算法。
3、熟悉生成圆的中点算法和正负法。
4、理解圆生成的基本原理。
二、实验步骤与内容:在光栅显示器上显示图形时,直线段或图形边界或多或少会呈锯齿状,原因是图形信号时连续,而在光栅显示系统中,用来表示图形的却是一个个离散的像素,这种用离散量表示连续两引起的失真现象称之为走样,用于减少或消除这种效果的技术称为饭走样技术。
采用反走样可适当减轻锯齿效果,但需要以额外的软件或者硬件来实现。
通常的,我们利用画图算法,在屏幕上生成任意一段八分之一圆弧,再利用图的对称性,将那段圆弧扩展为一个整1.圆的特征圆被定义为到给定中心位置(x,y)距离为r的点集。
圆心位于远点的圆有4条对称轴:分别为:x=0,y=0,x=y,x=-y.若已知圆弧上一点(x,y),可以得到其关于4条对称轴的其他7个点,这个性质叫做8对称型。
因此只要扫描转换八分之一圆弧,就可以求出整个圆弧的像素集。
2.生成圆的中点算法在第i点已经选择A时,第i+1点只能选择B或C,D为圆弧与直线BC的交点,M为线段BC的中点,M在圆内选B,M在圆外选C设圆的方程为F(x,y)=0,M在圆内时F(M)<0, M在圆外时F(M)>0 ,M在圆上时F(M)=0主要算法:设d i=F(M),则d i>0,选C;d i< = 0,选Bd i=F(x i +1,y i,r - 1/2)= (x i +1)2+(y i,r - 1/2)2- R2d i+1=F(x i+1 +1,y i+1,r - 1/2)= (x i+1 +1)2+(y i+1,r - 1/2)2- R2初始条件:(x0,y0,r)=(0,R)d0=F(x0 +1,y0,r – 1/2)=5/4-R结束条件:x i>=y i圆心为任意点(x c,y c)。
AutoCAD课程上机实验报告实验序号:实验三实验名称:二维图形编辑(一)班级:08计科学号:2008032514 姓名:黄智华分组人数:5 人指导老师:李伙友实验日期:年月日实验成绩:一、实验目的及要求目的:1.理解选择集概念,熟练掌握各种对象选择方式。
2.熟练掌握二维图形编辑(ERASE、COPY、MIRROR、OFFSET、ARRAY、MOVE、LENGTH、TRIM、EXEND、BREAK等)命令的使用。
3.熟悉掌握绘图环境设置(图形单位、图形范围、对象颜色、对象线型和对象线宽)。
4.熟练掌握辅助绘图工具(栅格显示、网格捕捉、正交模式、对象捕捉和自动跟踪)。
要求:1.将图形绘制在文件“实验三二维图形编辑(一)”中,图形界限为120*90,绘图尺寸自定,但要与原图相似。
2.绘图时设置合适的绘图环境。
3.绘图时使用合适的绘图工具。
4.使用绘图、编辑、辅助绘图命令绘制图形。
5.尺寸标注略。
二、实验环境本次上机实践所使用的平台为:windows7操作系统所使用的软件为:AutoCAD 2006三、实验内容绘制图s5-1、图s5-2、图s5-3、图s5-4所示的图形。
四、实验主要步骤1.绘制图s5-1:1)启动AutoCAD2006系统,进入AutoCAD2006绘图界面。
2)用LIMITS命令设置图形界限为120-90。
3)用ZOOM命令及“全部”选项设置绘图区为图界范围。
4)用LINE命令、正交方式和45度极轴追踪方式绘制图s5-1的基本图形(三角旗)。
5)用COPY、MOVE、MIRROR、ROTATE和ALIGN命令及对象捕捉绘制s5-1其余图形。
2.绘制图s5-2:1)用LINE命令、网格捕捉喝正交方式绘制辅助线。
2)用CIRCLE和LINE命令,以及对象捕捉功能绘制图形。
3)用TRIM命令修剪圆绘制图形。
4)用ERASE命令删除辅助线,生成s5-2图形。
3.绘制图形s5-31)用CIRCLE和LINE命令,以及对象捕捉功能绘制图形。
实验3实验报告格式《计算机图形学》实验3实验报告实验题目:直线(光栅化)实数型Bresenham 算法在用户坐标系和Java AWT 坐标系下显示图像实验内容:1 直线(光栅化)实数型Bresenham 算法原理及程序。
2 直线(光栅化)DDA 算法原理及程序。
3 在用户坐标系和Java AWT 坐标系下显示图像的算法原理及实现。
写程序调用验证之。
参考资料:1 课件:光栅图形生成算法.PP T2 Bresenham 算法演示程序已经在MyCanvas 包里,DDA 算法applet 演示程序DDA.java3 有一个示范程序imageDrawApplet.java基本概念:(详细叙述自己对实验内容的理解) 直线(光栅化):画一条从(x1, y1)到(x2, y2)的直线,实质上是一个发现最佳逼近直线的像素序列、并填入色彩数据的过程。
这过程称为直线光栅化。
Bresenham 算法:Bresenham 直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在 n 维光栅上最接近的点。
这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。
DDA 算法:DDA 算法(Digital Differential Analyzer ),又称数值微分法,是计算机图形学中一种基于直线的微分方程来生成直线的方法。
算法设计:(详细叙述自己设计的Bresenham 算法以及程序的功能、不同坐标系下图像显示的算法)程序功能:用DDA 算法画出直线,在不同的坐标系下显示图像。
Bresenham 算法:用坐标为(xi ,yi,r)的象素来表示直线上的点,则第i+1个点只能在C 和D 中选取。
令d1=BC ,d2=DBd1-d2=(yi+1–yi,r)-( yi,r+1-yi+1)=2yi+1–yi,r –(yi,r+1)= 2yi+1–2yi,r –1x i x i+1令ε(xi+1)= yi+1–yi,r–0.5=BC-AC=BA=B-A= yi+1–(yi,r+ yi,r+1)/2当ε(xi+1)≥0时,yi+1,r= yi,r+1,即选D点,即下个点(xi+1,yi+1 )对应的象素(xi +1,yi+1,r )为(xi+1,yi,r+1 )当ε(xi+1)<0时,yi+1,r= yi,r,即选C点,即下个点(xi+1,yi+1 )对应的象素(xi +1,yi+1,r )为(xi+1,yi,r )ε(xi+1)= yi+1–yi,r–0.5ε(xi+1)≥0时,yi+1,r= yi,r+1ε(xi+1)<0时,yi+1,r= yi,r用户坐标系下图像显示算法:定义自己的坐标系,将用户坐标系转换为Java awt坐标,调用Graphics类的drawImage方法即可。
计算机图形学实验报告一、实验目的本次计算机图形学实验旨在深入了解和掌握计算机图形学的基本原理、算法和技术,通过实际操作和编程实现,提高对图形生成、处理和显示的能力,培养解决实际图形问题的思维和实践能力。
二、实验环境本次实验使用的编程语言为 Python,借助了相关的图形库如Pygame 或 matplotlib 等。
开发环境为 PyCharm 或 Jupyter Notebook。
三、实验内容(一)二维图形的绘制1、直线的绘制使用 DDA(Digital Differential Analyzer)算法或 Bresenham 算法实现直线的绘制。
通过给定直线的起点和终点坐标,在屏幕或图像上绘制出直线。
比较两种算法的效率和准确性,分析其优缺点。
2、圆的绘制采用中点画圆算法或 Bresenham 画圆算法绘制圆。
给定圆心坐标和半径,生成圆的图形。
研究不同半径大小对绘制效果和计算复杂度的影响。
(二)图形的填充1、多边形填充实现扫描线填充算法,对任意多边形进行填充。
处理多边形的顶点排序、交点计算和填充颜色的设置。
测试不同形状和复杂度的多边形填充效果。
2、图案填充设计自定义的填充图案,如纹理、条纹等,并将其应用于图形填充。
探索如何通过改变填充图案的参数来实现不同的视觉效果。
(三)图形的变换1、平移、旋转和缩放对已绘制的图形(如矩形、三角形等)进行平移、旋转和缩放操作。
通过矩阵运算实现这些变换。
观察变换前后图形的位置、形状和方向的变化。
2、组合变换将多个变换组合应用于图形,如先旋转再平移,或先缩放再旋转等。
分析组合变换的顺序对最终图形效果的影响。
(四)三维图形的表示与绘制1、三维坐标变换学习三维空间中的平移、旋转和缩放变换矩阵,并将其应用于三维点的坐标变换。
理解如何将三维坐标映射到二维屏幕上显示。
2、简单三维图形绘制尝试绘制简单的三维图形,如立方体、球体等,使用线框模型或表面模型。
探讨不同的绘制方法和视角对三维图形显示的影响。
武汉轻工大学数学与计算机学院指导教师:吴海涛班级:计科1001学号:100511316姓名:张雄实验2 基本图形生成算法实验目的和要求:理解基本图形生成算法的基本原理,进一步掌握OpenGL编程技术。
实验环境:Visual C++ 6.0或以上版本,Windows 2000或以上版本,OpenGL图形库实验内容:基于像素串的区域填充实现文献[1] 126-127页中沿扫描线填充水平像素段的4-连通边界填充算法。
用几个区域对这个程序进行测试。
实验程序:#include <GL/glut.h>#include <math.h>typedef float Color[3];rgbColorEqual(Color c1,Color c2){if(abs(c1[1]-c2[1])<0.001 && abs(c1[2]-c2[2])<0.001 && abs(c1[0]-c2[0])<0.001)return true;elsereturn false;}void setPixel(GLint x, GLint y){glBegin(GL_POINTS);glVertex2i(x, y);glEnd();}void getPixel(GLint x, GLint y, Color c){glReadPixels(x,y,1,1,GL_RGB,GL_FLOAT,c);}void BoundaryFill8(int x, int y,Color fillColor,Color borderColor){Color currentColor;getPixel(x,y,currentColor);if((!rgbColorEqual(currentColor,fillColor))&&(!rgbColorEqual(currentColor,borderColor))){//setColor(fillColor);setPixel(x,y);BoundaryFill8( x+1, y, fillColor, borderColor);BoundaryFill8( x+1, y+1, fillColor, borderColor);BoundaryFill8( x+1, y-1, fillColor, borderColor);BoundaryFill8( x-1, y, fillColor, borderColor);//BoundaryFill8( x-1, y-1, fillColor, borderColor);//BoundaryFill8( x-1, y+1, fillColor, borderColor);//BoundaryFill8( x, y, fillColor, borderColor);//BoundaryFill8( x, y+1, fillColor, borderColor);//BoundaryFill8( x, y-1, fillColor, borderColor);}}void init(void){glClearColor(1.0,1.0,1.0,0.0);glMatrixMode (GL_PROJECTION);gluOrtho2D (0.0, 200.0, 0.0, 200.0);}void Draw(void){Color a={0.0,0.0,1.0},b={0.0,1.0,1.0};glColor3fv(b);glClear(GL_COLOR_BUFFER_BIT);//设置边界线宽,否则填充时会溢出glLineWidth(4.0);//绘制多边形区域glBegin(GL_LINE_LOOP);glVertex2i(90, 40);glVertex2i(120, 100);glVertex2i(90, 160);//glVertex2i(60, 160);glVertex2i(60, 40);glEnd();glColor3fv(a);BoundaryFill8(70,60,a,b);glFlush();}void main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(200, 200);glutCreateWindow("4连通边界填充算法!");init();glutDisplayFunc(Draw);glutMainLoop();}实验截图:实验总结:通过本次实验让我了解了填充算法的基本原理,学会了如何实现填充算法,实现了一些基本图形的填充。
实验一:二维图形的绘制和变换一、实验目的掌握基本的图形学算法,熟悉VC下图形学的编程,初步了解并使用OpenGL 绘制图形。
二、实验内容二维图形的绘制和变换,绘制包括直线、三角形、矩形,变换包括平移、旋转、缩放。
三、实验原理二维图形的绘制和变换:在图形系统中,矩阵是实现变换的标准方法。
平移变换、旋转变换和缩放变换的矩阵表示形式如下。
平移变换:P’=P+T。
旋转变换:P’=R*P。
缩放变换:P’=S*P。
引入齐次坐标后,平移、旋转和缩放变换的矩阵表示形式如下所示。
(1)平移变换:[1 0 0][x’, y’, 1] = [x, y, 1] [0 1 0][tx ty 1](2)旋转变换:[cosɵsinɵ0][x’, y’, 1] = [x, y, 1] [-sinɵcosɵ0][0 0 1](3)缩放变换:[s x0 0][x’, y’, 1] = [x, y, 1] [0 s y0][0 0 1]四、实验代码及结果1.编写对一个三角形分别实现平移、缩放、旋转等变化的源码及效果图。
实验核心代码void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glLoadIdentity ();glColor3f (1.0, 1.0, 1.0);glTranslatef(-100.0,-50.0,1.0);draw_triangle ();glLoadIdentity ();glTranslatef (0.0, 100.0, 1.0);draw_triangle ();glLoadIdentity ();glRotatef (90.0, 0.0, 0.0, 1.0);draw_triangle ();glLoadIdentity ();glScalef (0.5, 0.5, 1.0);draw_triangle ();glFlush ();}2. 实现如图功能#include<windows.h>#include <GL/glut.h>#include <stdlib.h>void init(void){glClearColor (0.0, 0.0, 0.0, 0.0);glShadeModel (GL_SMOOTH); }void draw_triangle(void){glShadeModel(GL_SMOOTH);glColor3f(0.2,0.7,0.30);glBegin (GL_TRIANGLES);//画出三角形,为混合色填充方式glVertex2f(50.0, 25.0);glColor3f(0.4,0.5,0.60);glVertex2f(150.0, 25.0);glColor3f(0.9,0.7,0.8);glVertex2f(100.0, 100.0);glEnd();}void display(void){glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glLoadIdentity ();glColor3f (1.0, 1.0, 1.0);glTranslatef(-100.0,-50.0,1.0);draw_triangle ();glLoadIdentity ();glTranslatef (0.0, 100.0, 1.0);glRotatef (90.0, 0.0, 0.0, 1.0);glScalef (0.5, 0.5, 1.0);draw_triangle ();//经过三种变换后画出图形glFlush ();}void reshape (int w, int h){glViewport (0, 0, (GLsizei) w, (GLsizei) h);glMatrixMode (GL_PROJECTION);glLoadIdentity ();if (w <= h)gluOrtho2D (-200.0, 250.0, -100.0*(GLfloat)h/(GLfloat)w,200.0*(GLfloat)h/(GLfloat)w);//调整裁剪窗口elsegluOrtho2D (-200.0*(GLfloat)w/(GLfloat)h,250.0*(GLfloat)w/(GLfloat)h, -50.0, 200.0);glMatrixMode(GL_MODELVIEW);int main(int argc, char** argv){glutInit(&argc, argv);glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);glutInitWindowSize (600, 600);glutInitWindowPosition (100, 100);glutCreateWindow (argv[0]);init ();glutDisplayFunc(display);glutReshapeFunc(reshape);glutMainLoop();return 0;}实验二:使用中点扫描算法绘制直线和圆一、实验目的掌握基本的图形学算法,熟悉VC下图形学的编程,初步了解并使用OpenGL 绘制图形。
太原工业学院实验报告
GetClientRect(&rect);//获得客户区的大小
pDC->SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系
pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口范围
pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区范围,x轴水平向右,y轴垂直向上
pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//客户区中心为原点
CDC memDC;//内存DC
CBitmap NewBitmap,*pOldBitmap;//内存中承载的临时位图
memDC.CreateCompatibleDC(pDC);//创建一个与显示pDC兼容的内存memDC
NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容位图
pOldBitmap=memDC.SelectObject(&NewBitmap);//将兼容位图选入memDC
memDC.FillSolidRect(rect,pDC->GetBkColor());//按原来背景填充客户区,否则是黑色
memDC.SetMapMode(MM_ANISOTROPIC);//memDC自定义坐标系memDC.SetWindowExt(rect.Width(),rect.Height());
memDC.SetViewportExt(rect.Width(),-rect.Height());
memDC.SetViewportOrg(rect.Width()/2,rect.Height()/2);
rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);
DrawWindowRect(&memDC);//绘制窗口
if(PtCount>=1)
{
memDC.MoveTo(Round(P[0].x),Round(P[0].y));
memDC.LineTo(Round(P[1].x),Round(P[1].y));
}
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY);//将内存memDC中的位图拷贝到显示pDC中
memDC.SelectObject(pOldBitmap);//恢复位图
NewBitmap.DeleteObject();//删除位图
}
(2)绘制裁剪窗口
void CTestView::DrawWindowRect(CDC* pDC)//绘制裁剪窗口
{
// TODO: Add your message handler code here and/or call default
pDC->SetTextColor(RGB(128,0,255));
pDC->TextOut(-10,Wyt+20,CString("窗口"));
CPen NewPen3,*pOldPen3;//定义3个像素宽度的画笔
NewPen3.CreatePen(PS_SOLID,3,RGB(255,128,0));
pOldPen3=pDC->SelectObject(&NewPen3);
pDC->Rectangle(Wxl,Wyt,Wxr,Wyb);
pDC->SelectObject(pOldPen3);
NewPen3.DeleteObject();
}
(3)Cohen-Sutherland算法
void CTestView::Cohen()//Cohen-Sutherland算法
{
CP2 p;//交点坐标
EnCode(P[0]);//起点编码
EnCode(P[1]);//终点编码
while(P[0].rc!=0 || P[1].rc!=0)//处理至少一个顶点在窗口之外的情况{
if((P[0].rc & P[1].rc)!=0)//简弃之
{
PtCount=0;
return;
}
if(0==P[0].rc)//确保P[0]位于窗口之外
{
CP2 Temp;
Temp=P[0];
P[0]=P[1];
P[1]=Temp;
}
UINT RC=P[0].rc;
double k=(P[1].y-P[0].y)/(P[1].x-P[0].x);//直线段的斜率
//窗口边界按左、右、下、上的顺序裁剪直线段
if(RC & LEFT)//P[0]点位于窗口的左侧
{
p.x=Wxl;//计算交点y坐标
p.y=k*(p.x-P[0].x)+P[0].y;
}
else if(RC & RIGHT)//P[0]点位于窗口的右侧
{
p.x=Wxr;//计算交点y坐标
p.y=k*(p.x-P[0].x)+P[0].y;
}
else if(RC & BOTTOM)//P[0]点位于窗口的下侧
{
p.y=Wyb;//计算交点x坐标
p.x=(p.y-P[0].y)/k+P[0].x;
}
else if(RC & TOP)//P[0]点位于窗口的上侧
{
p.y=Wyt;//计算交点x坐标
p.x=(p.y-P[0].y)/k+P[0].x;
}
EnCode(p);
P[0]=p;
}
}
void CTestView::EnCode(CP2 &pt)//端点编码函数
{
pt.rc=0;
if(pt.x<Wxl)
pt.rc=pt.rc|LEFT;
else if(pt.x>Wxr)
pt.rc=pt.rc|RIGHT;
if(pt.y<Wyb)
pt.rc=pt.rc|BOTTOM;
else if(pt.y>Wyt)
pt.rc=pt.rc|TOP;
}
(4)人机交互
void CTestView::OnDrawpic()
{
// TODO: Add your command handler code here
PtCount=0;
bDrawLine=TRUE;
MessageBox(CString("鼠标画线,剪刀裁剪"),CString("提示"),MB_OKCANCEL);
Invalidate(FALSE);
}
运行结果:
实验拓展:在屏幕上显示一个直线构成的图案,使用鼠标选择两点绘制矩形代表窗口对图案矩形裁剪。
核心代码:
void CTestView::ClipPolygon(CP2 *out,int Length,UINT Boundary)//裁剪多边形
{
if(0==Length)
return;
CP2 *pTemp=new CP2[Length];
for(int i=0;i<Length;i++)
pTemp[i]=out[i];
CP2 p0,p1,p;//p0-起点,p1-终点,p-交点
OutCount=0;
p0=pTemp[Length-1];
for(int i=0;i<Length;i++)
{
p1=pTemp[i];
if(Inside(p0,Boundary))//起点在窗口内
{
if(Inside(p1,Boundary))//终点在窗口内,属于内→内
{
Out[OutCount]=p1;//终点在窗口内
OutCount++;
}
else//属于内→外
{
p=Intersect(p0,p1,Boundary);//求交点
Out[OutCount]=p;
OutCount++;
}
}
else if(Inside(p1,Boundary))//终点在窗口内,属于外→内
{
p=Intersect(p0,p1,Boundary);//求交点
Out[OutCount]=p;
OutCount++;
Out[OutCount]=p1;
OutCount++;
}
p0=p1;
}
delete[] pTemp; }。