自由曲线和曲面的绘制.docx

上传人:b****5 文档编号:11990752 上传时间:2023-04-16 格式:DOCX 页数:35 大小:276.52KB
下载 相关 举报
自由曲线和曲面的绘制.docx_第1页
第1页 / 共35页
自由曲线和曲面的绘制.docx_第2页
第2页 / 共35页
自由曲线和曲面的绘制.docx_第3页
第3页 / 共35页
自由曲线和曲面的绘制.docx_第4页
第4页 / 共35页
自由曲线和曲面的绘制.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

自由曲线和曲面的绘制.docx

《自由曲线和曲面的绘制.docx》由会员分享,可在线阅读,更多相关《自由曲线和曲面的绘制.docx(35页珍藏版)》请在冰豆网上搜索。

自由曲线和曲面的绘制.docx

自由曲线和曲面的绘制

信息与计算科学专业基础课

ComputerGraphics

ReportOfcourseexperiment

计算机图形学课程实验报告

实验题目自由曲线和曲面的绘制

班级计算091

姓名张阳

学号3090811019

指导教师胡钢

日期2012-6-17

西安理工大学理学院应用数学系

二0一二年春季学期

实验4

自由曲线和曲面的绘制

实验说明

实验目的:

掌握自由曲线和曲面(包括Bezier曲线、曲面和B样条曲线、曲面)的生成算法思想,并能上机编程绘制相应的曲线、曲面和利用曲线、曲面进行简单的几何造型设计。

实验地点:

教九楼401数学系机房

实验要求(Direction):

1.每个学生单独完成;

2.开发语言为TurboC或C++,也可使用其它语言;

3.请在自己的实验报告上写明姓名、学号、班级;

4.每次交的实验报告内容包括:

题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;

5.自己保留一份可执行程序,考试前统一检查和上交。

实验内容

实验题一

1.1实验题目

上机编写一个能绘制Bezier曲线和B样条曲线的通用程序,并调试成功。

具体要求为:

(1)用户在运行程序时,可以根据提示信息来决定选择绘制Bezier曲线,还是B样条曲线;

(2)两种曲线控制顶点的个数和坐标值要求可以随机输入(即Bezier曲线和B样条曲线的次数和位置可以随机输入);(3)当用户输入控制点的坐标位置后,屏幕上生成曲线的同时显示其特征多边形;且在特征多边形的顶点处输出该顶点坐标;(4)要求在可执行程序后附上运行结果(两种曲线都至少附上一个结果图)。

1.2实验目的和意义

掌握Bezier曲线和B样条曲线的绘制方法。

1.3程序制作步骤(包括算法的基本思想、流程图、设计步骤等)

一、基本思想

(1)Bezier曲线:

是由一组折线来定义的,且第一个点和最后一个点在曲线上,第一条和最后一条折线分别表示出曲线在起点和终点处的切线方向。

Bezier曲线通常由(n+1)个顶点定义一个n次多项式。

(2)B样条曲线:

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),计算所有的P(ti)。

Step4:

依次连接每个P(ti),就得到Bezier或B样条曲线

1.4主程序

#include

#include

#include

#include

#include"graphics.h"

//usingnamespacestd;

#definepi3.1415926

/**************二维点类**********************/

classPoint

{

public:

doublex;

doubley;

Point(intx=0,inty=0)//构造函数

{

this->x=x;

this->y=y;

}

voidoperator=(Point&a)//重载=运算符

{

x=a.x;

y=a.y;

}

Pointoperator*(doublea)//重载*运算符

{

returnPoint(a*x,a*y);

}

Pointoperator+(Pointa)//重载+运算符

{

returnPoint(x+a.x,y+a.y);

}

voidoperator+=(Pointa)//重载+=运算符

{

x+=a.x;

y+=a.y;

}

}

/*

********************基本的函数*************************

*/

//求阶乘

longintFactorial(intn)

{

inti,sum=1;

if(n==0)

return1;

for(i=2;i<=n;i++)

sum*=i;

returnsum;

}

//求Bernstein基函数

doubleBernstein(inti,intn,doublet)

{

return(double)Factorial(n)/Factorial(i)/Factorial(n-i)*pow(t,i)*pow(1-t,n-i);

}

//求B_SplineBase基函数

doubleB_SplineBase(inti,intn,doublet)

{

doublesum=0;intj;

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);

}

returnsum/Factorial(n);

}

/*

********************曲线*************************

*/

//求Bezier曲线

voidBezier(Pointp[],intpn,intm)

{

//将t【0,1】分成多少等分m

doubleh=1.0/m;

doublet=0;

inti,j;

int*pB=(int*)malloc(sizeof(int)*(2*m+2));

Pointptemp(0,0);

for(j=0;j<=2*m+1;j+=2,t+=h)

{

ptemp.x=0;

ptemp.y=0;

for(i=0;i

{

ptemp+=p[i]*Bernstein(i,pn-1,t);

}

pB[j]=ptemp.x;

pB[j+1]=ptemp.y;

}

drawpoly(m+1,pB);

}

//求B样条曲线

voidB_Spline(Pointp[],intpn,intn,intm)//pn为p中点个数,n为次数,m为t的等分数

{

doubleh=1.0/m;

doublet=0;

inti,j,k;

int*pB=(int*)malloc(sizeof(int)*(2*m+2));

Pointptemp(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+=p[k+i]*B_SplineBase(i,n,t);

}

pB[j]=ptemp.x;

pB[j+1]=ptemp.y;

}

drawpoly(m+1,pB);

}

}

//画控制多边形

voiddrawControlPoly(Point*p,intpn)

{

setlinestyle(DASHED_LINE,0,0);

inti;charstr[60];

for(i=0;i

{

line(p[i].x,p[i].y,p[i+1].x,p[i+1].y);

sprintf(str,"%c%d%c%d%c",'(',(int)p[i].x,',',(int)p[i].y,')');

outtextxy(p[i].x,p[i].y,str);

}

sprintf(str,"%c%d%c%d%c",'(',(int)p[i].x,',',(int)p[i].y,')');

outtextxy(p[i].x,p[i].y,str);

setlinestyle(SOLID_LINE,0,0);

}

voidmain()

{

intgd,gm,i,choose,n,pn;charstr[60];

detectgraph(&gd,&gm);

/**********************测试曲线************************/

setcolor(RED);

//Pointp[]={Point(0,0),Point(100,100),Point(200,100),Point(300,0)};

cout<<"***********************************"<

cout<<"***输入0:

Bezier曲线"<

cout<<"***输入1:

B样条曲线"<

while

(1)

{

cin>>choose;

if(choose==1)

{

break;

}

elseif(choose==0)

{

break;

}

cout<<"输入错误,请重新输入:

";

}

if(choose==1)

{

cout<<"输入B样条曲线段次数:

";

cin>>n;

}

cout<<"输入控制顶点个数:

";

cin>>pn;

Point*p=newPoint[pn];

cout<<"输入控制顶点:

"<

for(i=0;i

{

cout<<"输入p"<

";

cin>>p[i].x>>p[i].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);//画出控制多边形

settextstyle(0,0,2);

if(choose==0)

{

sprintf(str,"%s%d%s","您所画的是:

",pn-1,"次Bezier曲线");

outtextxy(p[pn-1].x+200,p[0].y,str);

}

else

{

sprintf(str,"%s%d%s","您所画的是:

",n,"次B样条曲线");

outtextxy(p[pn-1].x+200,p[0].y,str);

}

sprintf(str,"%s%d","您所用控制顶点个数为:

",pn);

outtextxy(p[pn-1].x+200,p[0].y+textheight("2"),str);

outtextxy(p[pn-1].x+200,p[0].y+2*textheight("2"),"控制顶点坐标分别为");

for(i=0;i

{

sprintf(str,"%d%s%d",(int)p[i].x,"",(int)p[i].y);

outtextxy(p[pn-1].x+230,p[0].y+(i+3)*textheight("2"),str);

}

getch();

closegraph();

}

1.5运行结果图

实验题二

2.1实验题目

1).利用Bezier曲线及其拼接技术设计花瓶几何图案或汽车图案(注意:

使用Bezier曲线时曲线的次数不要超过10次)。

要求:

(1)此题中Bezier曲线的生成利用deCasteljau算法,不能用Bezier曲线的定义;

(2)屏幕上生成花瓶几何图案曲线的同时显示其特征控制多边形;且在特征多边形的顶点处输出该顶点坐标;(3)花瓶几何图案的具体形状可以自行设计,但运行结果图至少包括2个花瓶图案。

运行结果参考图如下所示。

2).利用二次或三次Bezier曲线(或B样条曲线)技术绘制每个同学自己的中文名字图案。

要求:

(1)中文汉字的笔画要求具有一定的宽度,笔画区域可以填充也可以不填充;

(2)中文汉字的字体(如宋体、楷体等)可以自己设定。

参考样例的运行结果如下图所示。

2.2实验目的和意义

掌握并通过程序实现Bezier曲线和B样条曲线的C0级拼接。

2.3程序制作步骤(包括算法的基本思想、流程图、设计步骤等)

一、算法思想

利用Bezier曲线和B样条曲线的C0级拼接实现复杂图形的绘制。

二、设计步骤

Step1:

输入构成花瓶或车曲线的控制顶点。

Step2:

画花瓶:

利用deCasteljau算法生成的Bezier曲线逐段绘制花瓶图案。

画汽车:

利用B样条曲线逐段绘制汽车图案。

Step3:

画出控制多边形。

Step4:

标出控制多边形顶点坐标。

2.4主程序

(1)汽车图案

#include

#include

#include

#include

#include"graphics.h"

#definepi3.1415926

classPoint

{

public:

doublex;

doubley;

Point(intx=0,inty=0)//构造函数

{

this->x=x;

this->y=y;

}voidoperator=(Point&a)//重载=运算符

{

x=a.x;

y=a.y;

}Pointoperator*(doublea)//重载*运算符

{

returnPoint(a*x,a*y);

}

Pointoperator+(Pointa)//重载+运算符

{

returnPoint(x+a.x,y+a.y);

}

voidoperator+=(Pointa)//重载+=运算符

{

x+=a.x;

y+=a.y;

}

}

/*

********************基本的函数*************************

*/

//求阶乘

longintFactorial(intn)

{

inti,sum=1;

if(n==0)

return1;

for(i=2;i<=n;i++)

sum*=i;

returnsum;

}

//求Bernstein基函数

doubleBernstein(inti,intn,doublet)

{

return(double)Factorial(n)/Factorial(i)/Factorial(n-i)*pow(t,i)*pow(1-t,n-i);

}

//求B_SplineBase基函数

doubleB_SplineBase(inti,intn,doublet)

{

doublesum=0;intj;

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);

}

returnsum/Factorial(n);

}

/*

********************曲线*************************

*/

//求Bezier曲线

voidBezier(Pointp[],intn,intm)

{

//将t【0,1】分成多少等分m

doubleh=1.0/m;

doublet=0;

inti,j;

int*pB=(int*)malloc(sizeof(int)*(2*m+2));

Pointptemp(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+=p[i]*Bernstein(i,n,t);

}

pB[j]=ptemp.x;

pB[j+1]=ptemp.y;

}

drawpoly(m+1,pB);

}

//利用迪卡斯递推算法实现Bezier曲线

voidBezierD(Pointp[],intn,intm)

{

Point*pp=(Point*)malloc(sizeof(Point)*(n+1));//用于循环

//将t【0,1】分成多少等分m

doubleh=1.0/m;

doublet=0;

inti,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;i<=n;i++)

pp[i]=p[i];

for(i=n;i>0;i--)

{

for(k=0;k

pp[k]=(pp[k]*(1-t))+(pp[k+1]*t);

}

pB[j]=pp[0].x;

pB[j+1]=pp[0].y;

}

drawpoly(m+1,pB);

}

//求B样条曲线

voidB_Spline(Pointp[],intpn,intn,intm)//pn为p中点个数,n为次数,m为t的等分数

{

doubleh=1.0/m;

doublet=0;

inti,j,k;

int*pB=(int*)malloc(sizeof(int)*(2*m+2));

Pointptemp(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+=p[k+i]*B_SplineBase(i,n,t);

}

pB[j]=ptemp.x;

pB[j+1]=ptemp.y;

}

drawpoly(m+1,pB);

}

}

voidCar()

{

inti;charstr[60];

Pointp[]=

{

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,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);

circle(750,410,60);

//画控制点(红色)

setcolor(RED);

moveto(p[0].x,p[0].y);

for(i=1;i<23;i++)

{

lineto(p[i].x,p[i].y);

circle(p[i].x,p[i].y,4);

sprintf(str,"%c%d%c%d%c",'(',(int)p[i].x,',',(int)p[i].y,')');

outtextxy(p[i].x,p[i].y,str);

}

lineto(p[0].x,p[0].y);

circle(p[0].x,p[0].y,4);

sprintf(str,"%c%d%c%d%c",'(',(int)p[0].x,',',(int)p[0].y,')');

outtextxy(p[0].x,p[0].y,str);

}

voidmain()

{

intgd,gm,choose;

detectgraph(&gd,&gm);

initgraph(&gd,&gm,"");//图形模式初始化

Car();

getch();

closegraph();

}

(2)画姓名

#include"graphics.h"

#include"math.h"

#include

voidmain()

{

floatx0=145,y0=125,x1=160,y1=110,x2=175,y2=90,x3=180,y3=60;

floatx4=145,y4=145,x5=165,y5=185,x6=190,y6=205,x7=200,y7=210;

floatz1=345,w1=50,z2=335,w2=75,z3=320,w3=100;//阳

floatz4=330,w4=115,z5=360,w5=120,z6=330,w6=155;

floatz7=323,w7=154,z8=310,w8=145;

floatn0=100,m0=155,n1=100,m1=165,n2=100,m2=200,n3=90,m3=225;

floatn4=85,m4=223,n5=80,m5=222,n6=60,m6=210;

intgdriver=DETECT,gmode;

intx,y;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 初中作文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1