《计算机图形学》作业第一次作业《计算机图形学》的主要研究内容及发展趋势:图形通常由点、线、面、体等几何元素和灰度、色彩、线型、线宽等非几何属性组成。
从处理技术上来看,图形主要分为两类,一类是基于线条信息表示的,如工程图、等高线地图、曲面的线框图等,另一类是明暗图,也就是通常所说的真实感图形。
计算机图形学一个主要的目的就是要利用计算机产生令人赏心悦目的真实感图形。
为此,必须建立图形所描述的场景的几何表示,再用某种光照模型,计算在假想的光源、纹理、材质属性下的光照明效果。
所以计算机图形学与另一门学科计算机辅助几何设计有着密切的关系。
事实上,图形学也把可以表示几何场景的曲线曲面造型技术和实体造型技术作为其主要的研究内容。
同时,真实感图形计算的结果是以数字图像的方式提供的,计算机图形学也就和图像处理有着密切的关系。
图形与图像两个概念间的区别越来越模糊,但还是有区别的:图像纯指计算机内以位图形式存在的灰度信息,而图形含有几何属性,或者说更强调场景的几何表示,是由场景的几何模型和景物的物理属性共同组成的。
计算机图形学的研究内容非常广泛,主要有以下几个方面:计算机图形学的应用;计算机图形设备和系统;国际标准化组织(ISO) 发布的图形标准;人机交互接口技术;基本图形实体、自由曲线和自由曲面的生成算法;图形变换和裁剪;曲面和实体造型算法;颜色、光照模型及真实感图形显示技术与算法等内容。
从计算机图形学目前学科发展来看,有以下几个发展趋势:与图形硬件的发展紧密结合,突破实时高真实感、高分辨率渲染的技术难点;研究和谐自然的三维模型建模方法;利用日益增长的计算性能,实现具有高度物理真实的动态仿真;研究多种高精度数据获取与处理技术,增强图形技术的表现;计算机图形学与图像视频处理技术的结合;从追求绝对的真实感向追求与强调图形的表意性转变。
第二次作业上机实习目的:1、在掌握计算机图形学的基本原理、算法和实现技术的基础上,通过编程实现简单的二维图形生成。
2、培养综合运用计算机高级语言(C语言)有关课程的知识去分析和解决实际问题的能力。
以进一步巩固,深化,扩展本课程所学到的理论知识。
3、通过计算机高级语言对图形程序的编写,调试,使学生掌握图形程序编写的一般方法和步骤,以及计算机图形学在机械设计中的应用的基础知识,树立理论联系实际的正确设计思想和严谨的工作作风。
实验一 DDA 算法生成直线原理:在图形设备上输出一条直线,是通过在应用程序中对每一条直线的端点坐标的描述,由输出设备将一对端点间的路径加以描绘来实现的。
对于水平线或垂直线,只要有了驱动设备使之动作的指令,一般都能准确地画出。
但对于任意斜率的直线,就要考虑算法了。
因此大多数图形设备,都只提供驱动x 方向和y 方向动作的信号。
这两个方向的信号用来指示绘图笔动作或电子束的偏移,或控制应赋值像素的地址。
假设已知直线段AB 的端点坐标是(x1,y1),(x2,y2),且dy/dx=m=常数,显然可以推导出下面的递推公式:1212x x y y y x --=∆∆ (1)又因为yy y i i ∆+=+1,所以yx x y y y y i i ∆--+=+12121 (2)这样每增加一个增量x ∆,便可以按(1)计算出1+i y 。
由于屏幕上的像素只能是整数,因此要经过取整运算,即](int),[(int)11++i i y x 处的像素点才是显示像素点。
然而,乘法运算和取整运算都需要较多的时间,因此产生直线的速度会受到影响。
显然,如果在式(2)中令1=∆x ,则可以避免做费时的乘法,公式可以简化为12121x x y y y y i i --+=+这时要注意m>1和m<1两种情况的发生。
如果是m>1的情况,那么在X 方向增加一个步长,就有可能在Y 方向构成一个比1大的步距。
遇到这种情况,就应当把y 当做是自变量,每次增加一个单位步长1,去计算因变量x ,即11+=+i i y y ,m y x x x x i i i ∆+=∆+=+1由于1=∆y ,所以m x x i i 11+=+。
这样才不至于一次逃过多行。
当然,也要对1+i y 进行取整运算,再决定要显示的像素。
这种情况如图1所示。
如果是m<1的情况,则x 为自变量,每次增加一个步长,去计算1+i y 的值,并取整以决定下一个该亮的点是像素点,如图2所示:图1 m>1 图2 m<1 代码:#include <graphics.h> #include <stdio.h> #define N 10.0 main() {int drive,mode,x1,y1,x2,y2,dx,dy,tx,ty,i,j,k,n; float xinc,yinc,x0,y0; drive=DETECT;initgraph(&drive,&mode,"c:\\TC20\\BGI"); cleardevice();for(i=0;i<800;i+=N) {line(i,0,i,800); line(0,i,800,i); }setbkcolor(5); setcolor(2);scanf("%d%d%d%d",&x1,&y1,&x2,&y2); line(x1,y1,x2,y2); dx=abs(x1-x2); dy=abs(y1-y2); if(dx>dy) n=dx; else n=dy;xinc=(float)dx/(float)n; yinc=(float)dy/(float)n; if(x1>=x2&&y1>=y2) k=1;else if(x1<x2&&y1<y2) k=2;else if(x1>x2&&y1<y2) k=3;else if(x1<x2&&y1>y2) k=4; switch(k) {case 1: tx=x1; x1=x2; x2=tx; ty=y1;y1=y2; y2=ty; case 2:x0=x1/N+0.5; y0=y1/N+0.5;for(j=0;j<=n;j+=N) {circle(N*(int)x0,N*(int)y0,2); x0+=xinc; y0+=yinc; }break; case 3: tx=x1; x1=x2; x2=tx; ty=y1; y1=y2; y2=ty; case 4:x0=x1/N+0.5; y0=y1/N+0.5;for(j=0;j<=n;j+=N) {circle(N*(int)x0,N*(int)y0,2); x0+=xinc; y0-=yinc; } }getch();closegraph(); } 总结:用DDA 算法产生直线比较精确,而且逻辑简单,易于用硬件实现。
但是,要作出发运算,影响了算法的效率。
实验二 Bresenham 算法生成直线Bresenham 算法原理:此算法的主要思想是借助于一个决策变量i d 来确定该点亮的像素点。
对于0<m<1的情况,如图3所示,Bresenham 算法的分析过程如下:假设一条直线段的起点坐标为),(11y x ,终点坐标为),(22y x ,平移变换很容易将起点坐标变为)0,0(,终点坐标为),(dy dx 。
因为x dx dy y ∙=,且dx dy r q s =++1,所以q r dx dy s -+=)1(。
又因为)1(11+-+=-=r dx dy q s t ,所以12)1(2121--+=-=+-=-q r dx dys s s t s整理得出:dx dy qdx rdy dx t s -+-=-2)(2)(;在所讨论的这种情况下,显然0>dx ,所以可以用0)(<-dx t s 作为选择is 为下一个该点亮的像素点的条件。
因为0<-t s ,则表示s<t 。
从图3中可以看出,在s<t 时应选择i s点。
定义id dx t s =-)(,并称之为决策变量,那么dxdy qdx rdy d i -+-=2)(2;从图3中可以看出,1-=i x r ,1-=i y q ,是表示前面一个亮点的坐标值,因此可以写出决策变量i d 的初值为dxdy dx y dy x di i i -+-=--22211。
将下标加1,则有dx dy dx y dy x di i i -+-=+2221,dx y y dy x x d d i i i i i i )(2)(2111--+---=-,11=--i i x x ,dxy y dy d d i i i i )(2211-+--+=图3 直线段与光栅网格如果0≥di ,则表示下一个亮点应该选i T 。
一旦选择了i T,则有11+=-i i y y ,此时决策变量1+i d 的表达式为)(21dx dy d d i i -+=+;如果0<di ,则表示下一个亮点为iS 。
一旦选择了iS ,则有1-=i i y y ,此时决策变量1+i d 的表达式为dyd d i i 21+=+。
这样,便得到一种迭代方法:有上一个决策变量i d 可以算出下个决策变量1i d +,再根据决策变量的正负对iT 、iS 进行选择。
上面讨论的是0>∆≥∆y x 的情况,如果是0>∆>∆x y 的情况,则要把x 和y 的变量位置互换。
对于0<∆y 或者是0<∆x 的情况,应该将表达式1+=y y 和1x +=x 换成1-=y y 或者1-=x x 。
代码:#include <graphics.h> #include <stdio.h> #define N 10.0 main() {int drive,mode,x1,y1,x2,y2,dx,dy,tx,ty,x0,y0,i,h;drive=DETECT;initgraph(&drive,&mode,"c:\\TC20\\BGI"); cleardevice();for(i=0;i<800;i+=N) {line(i,0,i,800); line(0,i,800,i); }setbkcolor(5); setcolor(2);scanf("%d%d%d%d",&x1,&y1,&x2,&y2); line(x1,y1,x2,y2); dx=x2-x1;dy=y2-y1;h=2*dx-dy;x0=x1/N+0.5;y0=y1/N+0.5;if(x1>x2&&y1>y2) {tx=x1;x1=x2;x2=tx;ty=y1;y1=y2;y2=ty;}if(dx>=dy)while(x0<x1){if(h<0)h+=2*dy;else{h+=2*(dy-dx);y0+=N;}x0+=N;circle(x0,y0,3);}else if(dx<dy) while(y0<y1){if(h<0)h+=2*dx;else{h+=2*(dx-dy);x0+=N;}y0+=N;circle(x0,y0,3);}if(x1>x2&&y1<y2) {tx=x1;x1=x2;x2=tx;ty=y1;y1=y2;y2=ty;}if(dx>=-dy)while(x0<x1){if(h<0)h+=2*dy;else{h+=2*(dy-dx);y0-=N;}x0+=N;circle(x0,y0,3); }else if(dx<-dy) while(y0<y1) {if(h<0) h+=2*dx; else {h+=2*(dx-dy); x0+=N; }y0-=N;circle(x0,y0,3); }getch();closegraph(); }实验三 角度DDA 算法生成圆弧原理:任何圆都可用多边形来逼近,其边数越多,圆弧越光滑,但是边数太多会浪费绘图时间。