《自由曲线和曲面的绘制.doc》由会员分享,可在线阅读,更多相关《自由曲线和曲面的绘制.doc(29页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、【精品文档】如有侵权,请联系网站删除,仅供学习与交流自由曲线和曲面的绘制.精品文档.信息与计算科学专业基础课Computer Graphics Report Of course experiment 计算机图形学课程实验 报 告实验题目 自由曲线和曲面的绘制 班 级 计算091 姓 名 张 阳 学 号 3090811019 指导教师 胡 钢 日 期 2012-6-17 西安理工大学理学院应用数学系二0一二年春季学期实验4自由曲线和曲面的绘制实验说明实验目的:掌握自由曲线和曲面(包括Bezier曲线、曲面和B样条曲线、曲面)的生成算法思想,并能上机编程绘制相应的曲线、曲面和利用曲线、曲面进行简单
2、的几何造型设计。实验地点: 教九楼401 数学系机房实验要求(Direction): 1.每个学生单独完成;2.开发语言为TurboC或C+,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。实验内容:实验题一1.1实验题目上机编写一个能绘制Bezier曲线和B样条曲线的通用程序,并调试成功。具体要求为:(1)用户在运行程序时,可以根据提示信息来决定选择绘制Bezier曲线,还是B样条曲线;(2)两种曲线控制顶点的个数和坐标值要求可
3、以随机输入(即Bezier曲线和B样条曲线的次数和位置可以随机输入);(3)当用户输入控制点的坐标位置后,屏幕上生成曲线的同时显示其特征多边形;且在特征多边形的顶点处输出该顶点坐标;(4)要求在可执行程序后附上运行结果(两种曲线都至少附上一个结果图)。1.2实验目的和意义掌握Bezier曲线和B样条曲线的绘制方法。1.3程序制作步骤(包括算法的基本思想、流程图、设计步骤等)一、基本思想(1)Bezier曲线:是由一组折线来定义的,且第一个点和最后一个点在曲线上,第一条和最后一条折线分别表示出曲线在起点和终点处的切线方向。Bezier曲线通常由(n+1)个顶点定义一个n次多项式。(2)B样条曲线
4、:B样条曲线段是由若干条曲线段光滑连接而成的。首先定义B样条曲线段。设给定n+1个型值点,用表示(i=0,1,2,n)。把n次参数曲线段:叫做B样条曲线段。与Bezier曲线类似,依次用线段连接中相邻两个型值点所得的折现多边形称为B特征多边形。二、设计步骤Step1:选择Bezier或B样条曲线绘图;Step2:若选择用Bezier曲线绘图,输入控制顶点个数,依次输入控制顶点坐标;若选择用B样条曲线绘图,输入B样条曲线段次数,输入控制顶点个数,依次输入控制顶点坐标;Step3:则将t 0,1区间剖分成m等分,对于每一个ti,i=0,1,m,根据式(1)或(2)都可以计算出一个P(ti),计算所
5、有的P(ti)。Step4:依次连接每个P(ti),就得到Bezier或B样条曲线1.4主程序#include#include#include#include#includegraphics.h/using namespace std;#define pi 3.1415926/* 二维 点类 */class Pointpublic:double x;double y;Point(int x=0,int y=0) /构造函数this-x = x;this-y = y;void operator=(Point &a) /重载=运算符x=a.x;y=a.y;Point operator*(doubl
6、e a) /重载*运算符return Point(a*x,a*y); Point operator+(Point a) /重载+运算符return Point(x+a.x,y+a.y);void operator+=(Point a) /重载+=运算符x+=a.x;y+=a.y;* 基本的函数 */求阶乘long int Factorial(int n) int i,sum=1;if(n=0)return 1;for(i=2;i=n;i+)sum *= i;return sum;/求Bernstein基函数double Bernstein(int i,int n,double t)return
7、 (double)Factorial(n)/Factorial(i)/Factorial(n-i)*pow(t,i)*pow(1-t,n-i);/求B_SplineBase基函数double B_SplineBase(int i,int n,double t)double sum = 0; int j;for(j=0;j=n-i;j+)sum+=pow(-1,j)*Factorial(n+1)/Factorial(j)/Factorial(n+1-j)*pow(t+n-i-j,n); return sum/Factorial(n);* 曲线 */求Bezier曲线void Bezier(Poi
8、nt p,int pn,int m)/将t【0,1】分成多少等分 mdouble h = 1.0/m;double t = 0;int i,j;int *pB = (int *)malloc(sizeof(int)*(2*m+2);Point ptemp(0,0);for(j=0;j=2*m+1;j+=2,t+=h)ptemp.x = 0;ptemp.y = 0;for(i=0;ipn;i+)ptemp += pi*Bernstein(i,pn-1,t);pBj = ptemp.x;pBj+1 = ptemp.y;drawpoly(m+1,pB);/求B样条曲线void B_Spline(Po
9、int p,int pn,int n,int m) /pn为p中点个数,n为次数,m为t的等分数double h = 1.0/m;double t = 0;int i,j,k;int *pB = (int *)malloc(sizeof(int)*(2*m+2);Point ptemp(0,0);for(k=0;k=pn-n-1;k+) /是由pn-n个n次拼接而成t = 0;for(j=0;j=2*m+1;j+=2,t+=h)ptemp.x = 0;ptemp.y = 0;for(i=0;i=n;i+)ptemp += pk+i*B_SplineBase(i,n,t);pBj = ptemp
10、.x;pBj+1 = ptemp.y;drawpoly(m+1,pB);/画控制多边形void drawControlPoly(Point *p,int pn)setlinestyle(DASHED_LINE,0,0);int i; char str60;for(i=0;ipn-1;i+)line(pi.x,pi.y,pi+1.x,pi+1.y);sprintf(str,%c%d%c%d%c,(,(int)pi.x,(int)pi.y,);outtextxy(pi.x,pi.y,str);sprintf(str,%c%d%c%d%c,(,(int)pi.x,(int)pi.y,);outtex
11、txy(pi.x,pi.y,str);setlinestyle(SOLID_LINE,0,0);void main() int gd,gm,i,choose,n,pn; char str60;detectgraph(&gd,&gm);/* 测试曲线 */setcolor(RED);/Point p = Point(0,0),Point(100,100),Point(200,100),Point(300,0);cout*endl;cout* 输入 0: Bezier曲线 endl;cout* 输入 1: B样条 曲线 choose;if(choose=1)break; else if(choos
12、e=0)break;cout输入错误,请重新输入:;if(choose=1)coutn;coutpn;Point *p = new Pointpn;cout输入控制顶点:endl;for(i=0;ipn;i+)cout输入pi+1pi.xpi.y;initgraph(&gd,&gm,); /图形模式初始化setcolor(GREEN);if(choose=0)Bezier(p,pn,100); /画Bezier曲线else B_Spline(p,pn,n,100); /画B样条曲线setcolor(WHITE);drawControlPoly(p,pn); /画出控制多边形 settextst
13、yle(0,0,2);if(choose=0)sprintf(str,%s%d%s,您所画的是: ,pn-1, 次Bezier曲线);outtextxy(ppn-1.x+200,p0.y,str);elsesprintf(str,%s%d%s,您所画的是: ,n, 次B样条曲线);outtextxy(ppn-1.x+200,p0.y,str);sprintf(str,%s%d,您所用控制顶点个数为: ,pn);outtextxy(ppn-1.x+200,p0.y+textheight(2),str);outtextxy(ppn-1.x+200,p0.y+2*textheight(2),控制顶点
14、坐标分别为);for(i=0;ipn;i+)sprintf(str,%d%s%d,(int)pi.x, ,(int)pi.y); outtextxy(ppn-1.x+230,p0.y+(i+3)*textheight(2),str);getch();closegraph();1.5运行结果图:实验题二2.1实验题目1).利用Bezier曲线及其拼接技术设计花瓶几何图案或汽车图案(注意:使用Bezier曲线时曲线的次数不要超过10次)。要求:(1)此题中Bezier曲线的生成利用de Casteljau算法,不能用Bezier曲线的定义;(2)屏幕上生成花瓶几何图案曲线的同时显示其特征控制多边形
15、;且在特征多边形的顶点处输出该顶点坐标;(3)花瓶几何图案的具体形状可以自行设计,但运行结果图至少包括2个花瓶图案。运行结果参考图如下所示。2).利用二次或三次Bezier曲线(或B样条曲线)技术绘制每个同学自己的中文名字图案。要求:(1)中文汉字的笔画要求具有一定的宽度,笔画区域可以填充也可以不填充;(2)中文汉字的字体(如宋体、楷体等)可以自己设定。参考样例的运行结果如下图所示。2.2实验目的和意义掌握并通过程序实现Bezier曲线和B样条曲线的C0级拼接。2.3程序制作步骤(包括算法的基本思想、流程图、设计步骤等)一、算法思想 利用Bezier曲线和B样条曲线的C0级拼接实现复杂图形的绘
16、制。二、设计步骤 Step1:输入构成花瓶或车曲线的控制顶点。 Step2:画花瓶:利用de Casteljau算法生成的Bezier曲线逐段绘制花瓶图案。 画汽车:利用B样条曲线逐段绘制汽车图案。 Step3:画出控制多边形。 Step4:标出控制多边形顶点坐标。2.4主程序(1)汽车图案#include#include#include#include#includegraphics.h#define pi 3.1415926class Pointpublic:double x;double y;Point(int x=0,int y=0) /构造函数this-x = x;this-y =
17、y;void operator=(Point &a) /重载=运算符x=a.x;y=a.y;Point operator*(double a) /重载*运算符return Point(a*x,a*y); Point operator+(Point a) /重载+运算符return Point(x+a.x,y+a.y);void operator+=(Point a) /重载+=运算符x+=a.x;y+=a.y;* 基本的函数 */求阶乘long int Factorial(int n) int i,sum=1;if(n=0)return 1;for(i=2;i=n;i+)sum *= i;re
18、turn sum;/求Bernstein基函数double Bernstein(int i,int n,double t)return (double)Factorial(n)/Factorial(i)/Factorial(n-i)*pow(t,i)*pow(1-t,n-i);/求B_SplineBase基函数double B_SplineBase(int i,int n,double t)double sum = 0; int j;for(j=0;j=n-i;j+)sum+=pow(-1,j)*Factorial(n+1)/Factorial(j)/Factorial(n+1-j)*pow(
19、t+n-i-j,n); return sum/Factorial(n);* 曲线 */求Bezier曲线void Bezier(Point p,int n,int m)/将t【0,1】分成多少等分 mdouble h = 1.0/m;double t = 0;int i,j;int *pB = (int *)malloc(sizeof(int)*(2*m+2);Point ptemp(0,0);for(j=0;j=2*m+1;j+=2,t+=h)ptemp.x = 0;ptemp.y = 0;for(i=0;i=n;i+)ptemp += pi*Bernstein(i,n,t);pBj = p
20、temp.x;pBj+1 = ptemp.y;drawpoly(m+1,pB);/利用迪卡斯递推算法实现Bezier曲线void BezierD(Point p,int n,int m)Point *pp = (Point *)malloc(sizeof(Point)*(n+1); /用于循环/将t【0,1】分成多少等分 mdouble h = 1.0/m;double t = 0;int i,j,k;int *pB = (int *)malloc(sizeof(int)*(2*m+2);for(j=0;j=2*m+1;j+=2,t+=h)for(i=0;i0;i-)for(k=0;ki;k+
21、)ppk = (ppk*(1-t) + (ppk+1*t);pBj = pp0.x;pBj+1 = pp0.y;drawpoly(m+1,pB);/求B样条曲线void B_Spline(Point p,int pn,int n,int m) /pn为p中点个数,n为次数,m为t的等分数double h = 1.0/m;double t = 0;int i,j,k;int *pB = (int *)malloc(sizeof(int)*(2*m+2);Point ptemp(0,0);for(k=0;k=pn-n-1;k+) /是由pn-n个n次拼接而成t = 0;for(j=0;j=2*m+
22、1;j+=2,t+=h)ptemp.x = 0;ptemp.y = 0;for(i=0;i=n;i+)ptemp += pk+i*B_SplineBase(i,n,t);pBj = ptemp.x;pBj+1 = ptemp.y;drawpoly(m+1,pB);void Car()int i; char str60;Point p = Point(210,290),Point(210,350),Point(210,410),Point(310,410),Point(375,337), Point(417,337),Point(480,410),Point(670,410),Point(730
23、,337),Point(770,337),Point(830,410),Point(935,410),Point(935,350),Point(935,290),Point(830,290),Point(730,175),Point(625,175),Point(520,175),Point(470,232),Point(420,290),Point(315,290),Point(210,290),Point(210,350)/画车身(蓝色)setcolor(BLUE);B_Spline(p,23,2,100);/画轮子setcolor(GREEN);circle(395,410,60);ci
24、rcle(750,410,60);/画控制点(红色)setcolor(RED);moveto(p0.x,p0.y);for(i=1;i23;i+)lineto(pi.x,pi.y);circle(pi.x,pi.y,4);sprintf(str,%c%d%c%d%c,(,(int)pi.x,(int)pi.y,);outtextxy(pi.x,pi.y,str);lineto(p0.x,p0.y);circle(p0.x,p0.y,4);sprintf(str,%c%d%c%d%c,(,(int)p0.x,(int)p0.y,);outtextxy(p0.x,p0.y,str);void ma
25、in() int gd,gm,choose;detectgraph(&gd,&gm);initgraph(&gd,&gm,); /图形模式初始化Car(); getch();closegraph();(2)画姓名#includegraphics.h#includemath.h#includevoid main() float x0=145,y0=125,x1=160,y1=110,x2=175,y2=90,x3=180,y3=60; float x4=145,y4=145,x5=165,y5=185,x6=190,y6=205,x7=200,y7=210; float z1=345,w1=50
26、,z2=335,w2=75,z3=320,w3=100;/阳 float z4=330,w4=115,z5=360,w5=120,z6=330,w6=155; float z7=323,w7=154,z8=310,w8=145; float n0=100,m0=155,n1=100,m1=165,n2=100,m2=200,n3=90,m3=225; float n4=85,m4=223,n5=80,m5=222,n6=60,m6=210; int gdriver=DETECT,gmode; int x,y; float i,dt,t; initgraph(&gdriver,&gmode,D:
27、TC);/*初始化图形系统*/ setcolor(GREEN); setlinestyle(0,0,2); line(50,50,100,50);/1 setlinestyle(0,0,4); line(100,50,100,100);/2 line(50,100,100,100);/3 line(50,100,50,155);/4 line(50,155,100,155);/5 for(i=0;i=50;i+) dt=1/(float)50; t=i*dt; x=n0*(1-t)*(1-t)*(1-t)+n1*3*t*(1-t)*(1-t)+n2*3*t*t*(1-t)+n3*t*t*t;
28、y=m0*(1-t)*(1-t)*(1-t)+m1*3*t*(1-t)*(1-t)+m2*3*t*t*(1-t)+m3*t*t*t; if(i=0) moveto(x,y); lineto(x,y); setlinestyle(0,0,3); for(i=0;i=50;i+) dt=1/(float)50; t=i*dt; x=n3*(1-t)*(1-t)*(1-t)+n4*3*t*(1-t)*(1-t)+n5*3*t*t*(1-t)+n6*t*t*t; y=m3*(1-t)*(1-t)*(1-t)+m4*3*t*(1-t)*(1-t)+m5*3*t*t*(1-t)+m6*t*t*t; if(
29、i=0) moveto(x,y); lineto(x,y); line(90,130,195,130);/7 setlinestyle(0,0,4); line(125,50,125,225);/8 n0=125,m0=225,n1=140,m1=215,n2=150,m2=195,n3=155,m3=190; for(i=0;i=50;i+) dt=1/(float)50; t=i*dt; x=n0*(1-t)*(1-t)*(1-t)+n1*3*t*(1-t)*(1-t)+n2*3*t*t*(1-t)+n3*t*t*t; y=m0*(1-t)*(1-t)*(1-t)+m1*3*t*(1-t)
30、*(1-t)+m2*3*t*t*(1-t)+m3*t*t*t; if(i=0) moveto(x,y); lineto(x,y); for(i=0;i=30;i+) dt=1/(float)30; t=i*dt; x=x0*(1-t)*(1-t)*(1-t)+x1*3*t*(1-t)*(1-t)+x2*3*t*t*(1-t)+x3*t*t*t; y=y0*(1-t)*(1-t)*(1-t)+y1*3*t*(1-t)*(1-t)+y2*3*t*t*(1-t)+y3*t*t*t; if(i=0) moveto(x,y); lineto(x,y); for(i=0;i=20;i+) dt=1/(fl
31、oat)20; t=i*dt; x=x4*(1-t)*(1-t)*(1-t)+x5*3*t*(1-t)*(1-t)+x6*3*t*t*(1-t)+x7*t*t*t; y=y4*(1-t)*(1-t)*(1-t)+y5*3*t*(1-t)*(1-t)+y6*3*t*t*(1-t)+y7*t*t*t; if(i=0) moveto(x,y); lineto(x,y); line(300,50,300,205); setlinestyle(0,0,2); line(300,50,345,50); for(i=0;i=30;i+) dt=1/(float)30; t=i*dt; x=z1*(1-t)*
32、(1-t)+z2*2*t*(1-t)+z3*t*t; y=w1*(1-t)*(1-t)+w2*2*t*(1-t)+w3*t*t; if(i=0) moveto(x,y); setlinestyle(0,0,4); lineto(x,y); for(i=0;i=30;i+) dt=1/(float)30; t=i*dt; x=z3*(1-t)*(1-t)*(1-t)+z4*3*t*(1-t)*(1-t)+z5*3*t*t*(1-t)+z6*t*t*t; y=w3*(1-t)*(1-t)*(1-t)+w4*3*t*(1-t)*(1-t)+w5*3*t*t*(1-t)+w6*t*t*t; if(i=
33、0) moveto(x,y); lineto(x,y); for(i=0;i=30;i+) dt=1/(float)30; t=i*dt; x=z6*(1-t)*(1-t)+z7*2*t*(1-t)+z8*t*t; y=w6*(1-t)*(1-t)+w7*2*t*(1-t)+w8*t*t; if(i=0) moveto(x,y); setlinestyle(0,0,3); lineto(x,y); setlinestyle(0,0,2); line(360,52,420,52); line(360,127,420,127); line(360,203,420,203); setlinestyl
34、e(0,0,4); line(360,53,360,207); line(420,53,420,207); getch(); /*等待按一键结束*/ closegraph(); /*关闭图形系统,回到文本模式*/2.5运行结果图:实验题三3.1实验题目上机编写一个通用的绘制Bezier曲面(或B样条曲面)的程序,并输出运行结果。具体要求如下:(1)计算041班绘制Bezier曲面,计算042班绘制B样条曲面;(2)用户在运行程序时,可以根据提示信息来决定选择绘制双一次、双二次,还是双三次Bezier曲面(或B样条曲面);(3)在屏幕上生成曲面的同时要求画出其对应的曲面特征网格;(4)可以随机输
35、入控制曲面网格密度的精度值;(5)要求在可执行程序后附上运行结果(包括3个结果:双一次、双二次和双三次Bezier曲面或B样条曲面图)。3.2实验目的和意义掌握并通过程序实现Bezier曲面和B样条曲面的绘制。3.3程序制作步骤(包括算法的基本思想、流程图、设计步骤等)一、算法思想(1)Bezier曲面:在三维空间里,给定(n+1)(m+1)个点的空间点Pij(i=0,1,n;j=0,1,n),称nm次参数曲面:为nm次Bezier曲面。其中Pij为控制顶点,Bin(u),Bjm(v)为Bernstein基函数。二、设计步骤 Step1: 输入0或1选择Bezier曲面。 Step2: 输入控
36、制顶点个数和控制顶点坐标。 Step3: 输入1或2或3选择双一次、双二次,还是双三次Bezier曲面。 Step4: 输入由三维转向二维时,图像绕z轴的旋转角sita,绕x轴旋转角fai。 Step5: 将u0,1区间剖分成dn等分,对于每一个ui,i=0,1,dn,将v0,1区间剖分成dm等分,对于每一个vi,i=0,1,dm。 Step6: 根据式(1)或(2)都可以计算出一个P(ui, vi),计算所有的P(ui, vi)。 Step7: 对P(ui, vi)进行视图变换,绘制Bezier曲面。 Step8: 对控制顶点进行视图变换,绘制控制网格。 Step9: 标出控制多边形顶点坐标
37、。3.4主程序#include#include#include#include#includegraphics.h#define pi 3.1415926#define MAX 20/三维点类class Point3Dpublic:double x;double y;double z;Point3D(int x=0,int y=0,int z=0)this-x = x;this-y = y; this-z = z;void operator=(Point3D &a)x=a.x;y=a.y;z=a.z;Point3D operator*(double a)return Point3D(a*x,a
38、*y,a*z); Point3D operator+(Point3D a)return Point3D(x+a.x,y+a.y,z+a.z);void operator+=(Point3D a)x+=a.x;y+=a.y;z+=a.z;/求阶乘long int Factorial(int n) int i,sum=1;if(n=0)return 1;for(i=2;i=n;i+)sum *= i;return sum;double Bernstein(int i,int n,double t)return (double)Factorial(n)/Factorial(i)/Factorial(
39、n-i)*pow(t,i)*pow(1-t,n-i);/求Bezier曲面void BezierCurve(Point3D pMAX,int n,int m,int nd,int md,double sita,double fai) /将t【0,1】分成多少等分 mdouble hu = 1.0/nd;double hv = 1.0/md;double u = 0,v = 0;int i,j,k,l;sita = sita*pi/180;fai = fai*pi/180;/动态申请二维数组pBint *pB = new int*nd+1;for(i=0;i=nd;i+)pBi=new int2
40、*md+2;Point3D ptemp(0,0,0);for(i=0;i=nd;i+,u+=hu)v = 0;for(j=0;j= 2*md+1;j+=2,v+=hv)ptemp.x = 0;ptemp.y = 0;ptemp.z = 0;for(k=0;k=n;k+)for(l=0;l=m;l+)ptemp+=pkl*Bernstein(k,n,u)*Bernstein(l,m,v);pBij=ptemp.x*cos(sita)-ptemp.y*sin(sita)+500;pBij+1=-ptemp.x*sin(sita)*sin(fai)-ptemp.y*cos(sita)*sin(fai)+ptemp.z*cos(fai)+400;drawpoly(md+1,pBi);for(i=0;ind+1;