《计算机图形学报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学报告.docx(48页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、计算机图形学实验指导书、作业学期一2012-2013(2)班级:.测绘11-3班姓名:邹云龙学号:2110242测绘工程学院目录实验一直线段生成算法实现1实验二圆生成算法的实现5实验三二维图形几何变换的实现8实验四直线段裁剪算法的实现13实验五 Bezier曲线生成算法的实现19实验报告I21实验报告227实验报告332实验报告439实验报告546实验一直线段生成算法实现一、实验目的熟练掌握DDA直线生成算法、中点直线生成算法、Bresenham宜线生成算法的算法思想,了解各个算法中寻找直线段上的像素点的过程。二、实验学时2学时三、实验类型现代实验、验证性、自立式四、实验要求1 .根据指导书所
2、给的参考代码,每人至少实现两种直线段的生成算法。2 .要求能够实现任意起始点和终止点坐标的直线段的绘制。3 .能够实现不同线型(实线、虚线、点划线)、不同线宽(单像素宽度、多像素宽度)的直线段的绘制。五、实验原理与步骤原理:1 .数值微分法(DDA)设一直线段的起点和终点坐标分别为(xs , ys)和(xe, ye)。则直线段在X和Y方向的增量分别为:x=xe- xs , Ay= ye- ys设t=max (I Ax I, I Ayl)取时间步长为1/Zt,若当前像素点坐标为(xi, yi),则下一个像素点的坐标可由以下两式确定:xi+1=xi +dx=x i+Dx/Dtyi+l=yi+dy=
3、yi+Dy/Dt2 .中点宜线生成算法:假定直线斜率且已确定点亮象素点P (Xi ,Yi ),则下一个与直线最接近的像素只能是Pl 点或P2点。设M为中点,Q为交点,现需确定下一个点亮的象素。当M在Q的下方- P2离直线更近更近-取P2M在Q的上方- P1离直线更近更近-取P1M与Q重合,Pl, P2任取一点。假设直线方程为:ax+by+c=O 其中 a=yO-y 1, b=xl-xO, c=xOyl-xlyOF(x,y)=O点在直线上面F(x, y)0点在直线上方F(x, y)O-M在直线上方-取P1:此时再下一个象素的判别式为dl=F(xp+2, yp+0.5)=a(xp+2)+b(yp+
4、0.5)+c = a(xp +1)+b(yp +0.5)+c +a =d+a;增量为a若dM在直线下方-取P2;此时再下一个象素的判别式为d2= F(xp+2, yp+L 5)=a(xp+2)+b(yp+1.5)+c = a (xp +l)+b(yp +0.5)+c +a +b =d+a+b ;增量为a + b画线从(xO, yO)开始,d的初值dO=F(xO+l, y0+0.5)= a(x0+l)+b(yO +0.5)+c= F(xO, yO)+a+0.5b = a+0.5b由于只用d的符号作判断,为了只包含整数运算,可以用2d代替d来摆脱小数,提高效率,同时 d每次的增量也已相应乘2操作。
5、3 . Bresenham画线算法(以斜率在01之间的直线段为例,在第一象限内)这种情况下,选择X方向为计长方向,即增量dx=l。如书中P26图2-9所示,设Pi (xi,yi)是已选定的离直线最近的像素,现在要决定Pi+1是D还是C。显然,若d=0.5,则应选 D。(m= Ay/Ax)令6=m0.5(初值为111-0.5),即有:e 0时,选 Pi+l(xi+l, yi),更新 e=e+m;e=0时,选 Pi+l(xi+l, yi+1),更新 e=e+mT;为计算简便(整数计算),将判别式e替换为e=2eAx;初值 e=-Ax结论:得到递推公式e=0时,选 Pi+l(xi+l, yi+1);
6、e=e+2 Ay-2 Ax其中,x=xe-xs; Ay=ye-ys.同样方法可进行其它象限的推导。步骤:1 .在C#环境下,设计界面,在form窗口中添加4个文本框,三个命令按钮;2 .在代码编写窗口,编写DDA、中点直线生成算法、Bresenham宜线生成算法子程序,子程序名分别设为 DDALine, MidPointLine 和 BresenhamLine;3 .在三个命令按钮单击事件中分别根据文本框中给定的待绘制直线段起始点和终止点坐标调用相应的直线段生成子程序,Form中完成任意起始点直终止点的直线段的绘制。六、参考代码中点画线using System;using System.Col
7、lections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Drawing.Drawing2D;name space WindowsForms Application 15public partial class Forml : Form (Bitmap bmp;public Form 1()InitializeComponent();)
8、public void midpointline(int xO, int yO, int xl, int yl, Bitmap bmp)(int i,a, b, delta 1, delta2, d, x, y;a = yO-yl;b = x 1- xO;d =2* a + b;delta 1=2* a;delta2=2*(a + b);x = xO;y = yO;bmp.SetPixel(x, y, Color.Red);i=lwhile (x xl)if(d0)X+4-; y+;d += delta2;) else (x+;d += deltal;)i+;ifi%10=4bmp.SetPi
9、xel(x, y, Color.Red);bmp.SetPixel(x, y+1, Color.Red);bmp.SetPixel(x, y-1, Color.Red);private void button l_Click(object sender, Eve nt Args e)Graphics graphics = this.CreateGraphics();bmp = new Bitmap(this.ClientRectangle.Width ,this .ClientRectangle .Height);midpointline(40,60,200,150, bmp);graphic
10、s.Drawlmage(bmp, new Rectangle(0,0, this.ClientRectangle.Width,this.ClientRectangle.Height);七、实验报告要求及成绩评定标准1 .实验结束填写实验报告1。2 .成绩评定标准1)成果评定:根据学生程序运行状况,实验内容完成情况给予成果评定,成果评定成绩占60%;4)教师评价:根据考勤、学习态度、实验报告质量进行评定;综合以上评价,占40%。实验二圆生成算法的实现一、实验目的熟练掌握圆的中点生成算法和Bresenham生成算法的算法思想,了解各个算法中寻找圆上的像素点的过程。二、实验学时2学时三、实验类型现代
11、实验、验证性、自立式四、实验要求1 .根据指导书所给的参考代码,实现两种圆的生成算法。2 .要求能够实现任意圆心坐标和任意半径的圆的绘制。3 .能够实现不同线型(实线、虚线、点划线)、不同线宽(单像素宽度、多像素宽度)的圆绘制。五、实验原理与步骤原理:1 .圆的中点生成算法:利用圆的对称性,只须讨论1/8圆。第二个8分圆P (Xp, Yp)为当前点亮象素,那么,下一个点亮的象素可能是Pl (Xp+1, YP)或P2(Xp+1, Yp+1).构造函数:F (X, Y)=X2+ Y2- R2;贝ljF (X, Y)=0(X, Y)在圆上;F (X, Y)0(X, Y)在圆外。设 M 为 Pl、P2
12、间的中点,M=(Xp+l, Yp-0.5)有如下结论:F (M)M 在圆内-取 PlF (M)=0-M 在圆外-取 P2为此,可采用如下判别式:d = F(M)= F(Yp +1, Yp -0.5)=(Yp +1)2+(Yp -0.5)2- R2若d0,则Pl为下一个象素,那么再下一个象素的判别式为:dl = F(Xp +2, Yp -0.5)=(Xp +2)2+(Yp -0.5)2- R2= d +2Xp +3即d的增量为2Xp +3.若d=0,则P2为下一个象素,那么再下一个象素的判别式为:dl = F(xp +2, yp -1.5)=(xp +2)2+(yp -1.5)2- R2= d
13、+(2xp +3)+(-2 yp +2)即d的增量为2(xp - yp)+5.d的初值:dO = F(l, R-0.5)=1+(R-0.5)2- R2=1.25- R将d=0与d0看成一种情况,每次d的增量为整型值,因此此时0.25对d的符号没有影响,可将d 的初始值定为1-R2 .圆的Bresenham生成算法应取H,还是取Li现在从A点开始向右下方逐点来寻找弧AB耍用的点。如图中点Pi-1是已选中的一个表示圆弧上的点,根据弧AB的走向,下一个点应该从Hi或者Li中选择。显然应选离AB最近的点作为显示弧AB的点。假设圆的半径为R,显然,当xhi2+ yhi2-R2 N R2-(xli2+ y
14、li2)时,应该取Li。否则取Hi。令 di = xhi2+ yhi2+ xli2+ yli2-2R2显然,当 di 20时应该取 Li。否则取 Hi。剩下的问题是如何快速的计算di。设图中Pi-1的坐标为(xi-1, yi-1),则Hi和Li的坐标为(xi, yi-1)和(xi,yi-1-1)di = xi2+ yi-12+ xi2+(yiTT)2-2R2=2xi2+2yiT2-2yiT -2R2di+1=(xi +1)2+ yi2+(xi +1)2+(yi -1)2-2R2=2xi2+4xi +2yi2-2yi -2R2+3当 di取 Hi - yi=yi-l,则di+1= di +4xi
15、-l +6当 di20时-取 Li - yi=yiTT,则di+1= di +4(xi-l-yi-l)+10易知 x0=0, yO=R, xl=x0+l因此 d0=12+ y02+12+(y0-1)2-2R2=3-2y0=3-2R步骤:1 .在C#环境下,设计界面,在form窗口中添加3个文本框,两个命令按钮:2 .在代码编写窗口,编写圆的中点生成算法和Bresenham生成算法子程序,子程序名分别设为 MidPointCircle 和 BresenhamCirc1e;3 .在两个命令按钮单击事件中分别根据文本框中给定的待绘制圆的圆心和半径调用相应的圆的生成子程序,在Form中完成任意圆心坐标
16、和任意半径的圆的绘制。六、参考代码中点画圆using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Drawing.Drawing2D;name space WindowsFormsApplication 15public partial class Fonn 1: FormBi
17、tmap bmp;public Form 1()InitializeComponent();)public void midpointcircle(int r, Bitmap bmp)(int x, y,d;x =0; y = r; d =1- r;bmp.SetPixel(x, y, Co lor. Red);while (x y)(if(d=相对于y轴对称,*=x,y=相对于x=y对称,x= y,y= x相对于*=+对称,x=-y,y=-x相对于原点对称,=5 .错切变换错切包括沿X方向错切和沿y方向错切,点(x, y)沿X轴方向错切的系数为b,沿y轴方向错切的系数为 d,得到点(x,y)
18、,则有:x-x+bXy y=y+d Xx步骤:1 .在C#环境下,设计界面,在form窗口中添加5个命令按钮;2 .在代码编写窗口,编写二维平移、缩放、旋转、对称、错切算法子程序,子程序名分别设为批pinyi、 suofang、 xuanzhuan duichen cuoqie;3 .在Form中绘制一个初始图形,在5个命令按钮单击事件中分别调用相应的基本变换子程序,完成图形的变换。六、参考代码using System.Drawing;using System;using S y ste m .Col lections. Ge ne ri c;using System.ComponentMod
19、el;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Drawing.Drawing2D;name space WindowsForms Application 16public partial class Fonn 1: Form(int xO =100, yO =100, x 1=150, yl =100, x2=150, y2=150, x3=100, y3=150;Bitmap bmp;public For
20、m 1()InitializeComponent();)public void pingyi(int dx,int dy)(xO +=dx;y0+=dy;xl +=dx;yl +=dy;x2+=dx;y2+=dy;x3+=dx;y3+=dy;Graphics g = this.CreateGraphics();Pen pl = new Pen(Color.Blue);g.DrawLine(pl, xO, yO, x 1, yl);g.DrawLine(pl, xl, yl, x2, y2);g.DrawLine(pl, x2, y2, x3, y3);g.DrawLine(pl, x3, y3
21、, xO, yO);public void suofang(double sx,double sy)(double xOm, yOm, xlm, ylm, x2m, y2m, x3m, y3m;xOm = sx * xO;xlm = sx * xl;x2m = sx * x2;x3m = sx * x3;yOm = sy * yO;ylm = sy * yl;y2m = sy * y2;y3m = sy * y3;xO =(int)(Math.Round (xOm);xl =(int)(Math.Round(x Im);x2=(int)(Math.Round(x2m);x3=(int)(Mat
22、h.Round(x3m);yO =(int)(Math.Round(yOm);y 1=(int)(Math.Round(ylm);y2=(int)(Math.Round(y2m);y3=(int)(Math.Round(y3m);Graphics g = t hi s.Create Graph ics();Pen pl = new Pen(Color.LimeGreen);g.DrawLine(pl, xO, yO, xl, yl);g.DrawLine(pl, xl, yl, x2, y2);g.DrawLine(pl, x2, y2, x3, y3);g.DrawLine(pl, x3,
23、y3, xO, yO);)public void xuanzhuan(double a)(double xOm, yOm, xlm, ylm, x2m, y2m, x3m, y3m;xOm = xO * Math.Cos(a)- yO * Math.Sin(a);yOm = xO * Math.Sin(a)+ yO * Math.Cos(a);xlm = xl * Math.Cos(a)- yl * Math.Sin(a);ylm = xl * Math.Sin(a)+ yl * Malh.Cos(a);x2m = x2* Math.Cos(a)- y2* Math.Sin(a); y2m =
24、 x2* Math.Sin(a)+ y2* Math.Cos(a);x3m = x3* Math.Cos(a)- y3* Math.Sin(a);y3m = x3* Math.Sin(a)+ y3* Math.Cos(a);xO =(int)(Math.Round(xOm);xl =(int)(Math.Round(xlm);x2=(int)(Math.Round(x2m);x3=(int)(Math.Round(x3m);yO =(int)(Math.Round(yOm);yl =(int)(Math.Round(ylm);y2=(int)(Math.Round(y2m);y3=(int)(
25、Math.Round(y3m);Graphics g = this.CreateGraphics();Pen pl = new Pen(Color.LimeGreen);g.DrawLine(pl, xO, yO, xl, yl);g.DrawLine(pl, xl, yl, x2, y2);g.DrawLine(pl, x2, y2, x3, y3);g.DrawLine(pl, x3, y3, xO, yO);private void button l_Click(object sender, Eve nt Args e)(Graphics graphics = this.CreateGr
26、aphics();bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);Graphics g = this.CreateGraphics();Pen pl = new Pen(Color.Red);g.DrawLine(pl, xO, yO, xl, yl);g.DrawLine(pl, xl,yl, x2, y2);g.DrawLine(pl, x2, y2, x3, y3);g.DrawLine(pl, x3, y3, xO, yO);graphics.DrawImage(bmp, new Rec
27、tangle(O,0, this.ClientRectangle. Width, this.ClientRectangle.Height);private void button2_Click(object sender, EventArgs e)Graphics graphics = this.CreateGraphics();bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);Graphics g = this.CreateGraphics();Pen pl = new Pen(Color.Re
28、d);pingyi(60,60);graphics.DrawImage(bmp, new Rectangle(0,0, this.ClientRectangle. Width, this.ClientRectangle. Height);)private void button3_Click(object sender, EventArgs e)Graphics graphics = this.CreateGraphics();bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);Graphics g
29、 = this.CreateGraphics();Pen pl = new Pen(Color.Red); suofang(2,3);graphics.DrawImage(bmp, new Rectangle(0,0, this.ClientRectangle.Width, this.ClientRectangle. Height);private void button4_Click(object sender, EventArgs e)(Graphics graphics = this.CreateGraphics();bmp = new Bitm叩(this.ClientRectangl
30、e.Width, this.ClientRectangle.Height);Graphics g = this.CreateGraphics();Pen pl = new Pen(Color.Red);xuanzhuan(0.5);graphics.DrawImage(bmp, new Rectangle(0,0, this.ClientRectangle. Width, this.ClientRectangle.Height);)七、实验报告要求及成绩评定标准1 .实验结束填写实验报告3。2 .成绩评定标准1)成果评定:根据学生程序运行状况,实验内容完成情况给予成果评定,成果评定成绩占60%
31、;4)教师评价:根据考勤、学习态度、实验报告质量进行评定;综合以上评价,占40%。实验四直线段裁剪算法的实现一、实验目的掌握直线段裁剪的宜接求交算法、中点分割算法、Cohen-Sutherland算法和Liang-Barskey算法的算法思想及各算法的优缺点。二、实验学时2学时三、实验类型现代实验、验证性、自立式四、实验要求1 .根据指导书所给的参考代码,实现直线段裁剪的宜接求交算法、中点分割算法、Cohen-Sutherland 算法和Liang-Barskey算法中的至少一种算法;2 .要求能够实现任意直线段的裁剪。五、实验原理与步骤原理:1 .直接求交算法:线段是否显然不可见?是,则抛弃
32、整条线段,所谓显然不可见是指线段的两个端点同时位于窗口的某条边的外侧。(即构成线段的两端点同时位于在窗口上方或同时位于窗口下方或同时位于窗口左方或同时位于窗口右方o )线段是否完全可见,即线段的两个端点同时位于窗口内,是则转入计算线段与窗口边界的交点,并以此交点将线段分成两个部分;对于完全位于窗口外的部分抛弃;对剩下的部分转入1001100010100001窗口00000010yB010101000110保留并显示该线段。2. Cohen-Sutherland 算法:4区域编码对裁剪的线段的两个端点片(和凹)、巴(,巴)进行区域编码。设代码分别为Codel和Code2。根据Codel和Code
33、2的具体值,分下列三种情况:a.若Codel=Code2=0,说明线段的两个端点都在窗口的可见区域内,则整条线段必然在窗口内,应该保留整条线段,如图中的线段AB。b.Codel&Code2W0,则Codel与Code2至少有某一位同时为1,说明两端点必然同时处于某条边界的外侧,此时线段为显然不可见,应该舍弃整条线段,如图中的CD、EF、GHc.对于不是上述两种情况的线段,如图IJ、MN、0P则求出其与窗口边界及其延长线的交点,以此交点为线段分成两部分,其中在边界线外侧的那部分舍弃。如图,线段IJ,求出IJ与下边界的交点K,则将IK舍弃。d.对于线段剩余部分,如KJ,重复前述几个步骤。则至多重复
34、到第三次为止,剩下的线段或者完全窗口内则保留,或者完全在窗口外则舍弃。3 .中点分割算法从外出发找到该线段上的距离”最近的可见点,从片出发找到该线段上距离片最近的可见点。则这两个可见点间的部分就是原直线段4片在窗口内的部分。实际上,在离外最近的可见点和我离”最近的可见点的两个过程可同时进行,并且算法思想是相同的。原线段上距离与最近的可见点步骤:判断外是否可见,若玲可见,则为待找点;判断4片是否显然不可见,若是则说明原线段没有可见部分;先求出的中点,记为若凡也长度小于给定的一个任意小数,则认为该中点也为要找的点,循环结束,否则向下进行:若为&为显然不可见,则取与片代替原线段凡4,否则取为&代替原
35、线段外片,再对新产生的线段“片重复。4 .梁友栋-Barsky算法设要裁剪的线段是P0P1。P0P1和窗口边界交于A,B,C,D四点,见图。算法的基本思想是从A,B和P0三点中找出最靠近的P1点,图中要找的点是P0。从C,D和P1中找出最靠近P0的点。图中要找的点是C 点。那么POC就是P0P1线段上的可见部分。线段的参数表示x=xO+tAxy=yO+tAy0=t=()则y=yb为始边,y=yt为终边若 tl,则可见线段区间tl , tu若tu tl,则线段无可见部分始边和终边的确定及交点计算:令 QL二-AxDL= xO-xLQR= AxDR= xR-xOQB= - AyDB= yO-yBQ
36、T= AyDT= yT-yO交点为ti= Di / QiQi 0ti为与终边交点参数Qi =0Di 0时,分析另一 Di=L, R, B,T步骤:L2.在C#环境下,设计界面,在form窗口中添加4个文本框,两个命令按钮;;在代码编写窗口编写代码,单击命令按钮1绘制由文本框给出的起始点和终止点坐标确定的直线段,单击命令按钮2时,对由文本框给出的起始点和终止点坐标确定的直线段进行裁剪,显示裁剪结果。八、参考代码using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;us
37、ing System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;namespace WindowsFormsApplication31public partial class Forml : Form(public Form 1()InitializeComponent();private void button 1_Click(object sender, EventArgs e)int xl,xr,yb,yt,xl,x2,yl,y2,x,y,flag;flag =2;xl =2500;xr
38、=5500;yb =2500;yt =6500;Bitmap bmp;Graphics graphics = this.CreateGraphics();bmp = new Bitmap(this.ClientRectangle.Width, this.ClientRectangle.Height);Graphics g = this.Create Graphics。;Pen pl = new Pen(Color.Red);g.DrawLine(pl,2500,2500,2500,6500);g.DrawLine(pl,2500,6500,5500,6500);g.DrawLine(pl,55
39、00,6500,5500,2500);g.DrawLine(pl,5500,2500,2500,2500);xl = int.Parse (textBoxl .Text);yl = int.Parse(textBox2.Text);x2= int.Parse(textBox3.Text);y2= int.Parse(textBox4.Text);if (xl xl & x2 xl)flag=1;elseif (xl = xl)(yl =(int)(yl +(xl - xl)*(y2- yl)/(x2- xl);xl = xl;)else(if (xl = xl & x2 yt & y2 yt)flag=1;elseif (yl yt & y2= yt)(yl =xl +(y2- yl)*(yt - yl)/(y2- yl);yl =yt;)else(if (yl yt)x = xl;y = yl;xl =(int)(xl +(x2- xl)*(yt - yl)/(y2- yl);yl =yt;x2= x;y2= y;if(xl xr& x2 xr)(flag=1;)else(if (xl xr & x2= xr)yl =(int)(yl +(y2- yl)*(xr - xl)/(x2- xl);xl = xr;elseif (xl
限制150内