计算机图形学实验报告2Word格式文档下载.docx
- 文档编号:19361127
- 上传时间:2023-01-05
- 格式:DOCX
- 页数:15
- 大小:102.99KB
计算机图形学实验报告2Word格式文档下载.docx
《计算机图形学实验报告2Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验报告2Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
利用Transform函数和键盘事件来改变参数,w,s,a,d分别控制绘制的kitty猫的上下左右的移动:
实现代码如下:
旋转:
利用gllookat();
函数设定了观察角度,并用鼠标事件改变参数,用实现观察视角的变化实现物体的旋转,代码如下:
缩放:
运用glScalef方法和键盘事件改变参数,实现物体的放大和缩小,代码如下:
(10)实现Laplacian方法的三维模型光顺操作,并观察三维模型光顺过程;
Laplacian方法的原理是利用目标点与其所有邻接点平均后的点的差向量,对目标点的坐标进行变换的过程,具体方法是:
1建立每个点的邻接顶点数组,存储每个点的邻接点
2对每个顶点的邻接点进行求平均,即将邻接点的坐标求和后除以邻接点个数,从而得到邻接平均点
3得到优化向量
优化向量=邻接平均点-目标点
4设定优化度参数λ,得到优化后的新坐标新坐标=目标点+λ*优化向量
在程序中,对于第num个顶点,我设定的变量为
目标点vArr
邻接平均点v0
优化向量l
新坐标数组vNewArr
具体代码如下:
I
for(inti
0;
i<
m;
i卄){
v0[0]+
VArr[ne∑tVArι∖num][ij
l][0];
vθ[l]+
vArr[nextVArr[num][i]-
-1]⑴;
vθ[2]+
VArr[nextVArr[num][il-
・1]⑵:
}
Eif(In!
=O){
for(inti=0;
3;
i十+)
vθ[i]/=m;
l[0]=vθEθ]-VArr[num][0];
1[1]=vθ[l]-VArr[num]11]:
1[2]=vθ[2]-vArr[num][2];
=VArr[num][θ]+l[0]*0.3;
=vArr[num][1]÷
1[1]*0.3;
=VArr[num][2]+1[2]*0.3;
v_IIUln:
i十+){
VXeWArr[nuπj[0]
VXeWArr[nuιrlLIl
VXeWArr[num][2]
for(Lnti=0:
vArr[i][0]=VNeWArr[i]10];
vArr[i][1]=VNeWArr[i][1]:
VArrLil[2]=VNeWArr[i][2]:
}
五、结果展示及说明计算面法向后直接绘制(未光顺):
光顺进行一次后
光顺多次后
利用点绘制结果为
旋转后
缩放后
平移后
六、心得体会
(1)计算面法向时法向量的方向没有运用右手方向,导致有的面法向向里,从而出现雪花
(2)在运用Laplacian算法进行求邻接平均点时未初始化邻接平均点数组,导致平均点的累加
从而出现越光顺越粗糙的现象
(3)在obj文件中面对应顶点数和顶点数组的标号相差1.在运用的时候需减1,面
从1开始记顶点,顶点数组从0开始记顶点
七、实验代码
#defineGLUT_DISABLE_ATEXIT_HACK
#include<
stdlib.h>
GL/glut.h>
stdio.h>
iostream>
string>
fstream>
sstream>
cmath>
vector>
usingnamespacestd;
intv_num=0;
//记录点的数量
intf_num=0;
//记录面的数量
intvn_num=0;
//记录法向量的数量
intvt_num=0;
GLfloat**vArr;
//存放点的二维数组
GLfloat**vNewArr;
//存放点的二维数组int**fvArr;
//存放面顶点的二维数组GLfloat**fnArr;
//存放面法向量的二维数组int**ftArr;
int**vfArr;
//存放顶点临接的面数的数组
int**nextVArr;
//存放下一个临界顶点的数组
GLfloat**vnArr;
//存放点法向量的二维数组strings1,s2,s3,s4;
GLfloatf2,f3,f4;
intnum1,num2,num3;
typedefGLfloatpoint3[3];
point3x,y,l;
//平面上的两个向量x,y和拉普拉斯向量l
staticGLfloattheta[]={0.0,0.0,0.0};
staticGLintaxis=2;
staticGLdoubleviewer[]={0.0,0.0,5.0};
/*initialviewerlocation*/
staticGLdoubleTran[]={0.0,0.0,0.0};
staticGLdoublesca=1.0;
voidgetLineNum(stringaddrstr)//获取点和面的数量
{
ifstreaminfile(addrstr.c_str());
//打开指定文件if(!
infile){
cout<
<
"
openerror!
<
endl;
exit
(1);
stringsline;
//每一行
inti=0,j=0;
while(getline(infile,sline))//从指定文件逐行读取
if(sline[0]=='
v'
)
{v_num++;
f'
{f_num++;
intreadfile(stringaddrstr)//将文件内容读到数组中去
//getLineNum(addrstr);
//new二维数组
vArr=newGLfloat*[v_num];
for(inti=0;
v_num;
i++){
vArr[i]=newGLfloat[3];
vNewArr=newGLfloat*[v_num];
for(inti=0;
vNewArr[i]=newGLfloat[3];
vnArr=newGLfloat*[vn_num];
vn_num;
vnArr[i]=newGLfloat[3];
vfArr=newint*[v_num];
vfArr[i]=newint[10];
for(intj=0;
j<
10;
j++){vfArr[i][j]=-1;
nextVArr=newint*[v_num];
nextVArr[i]=newint[10];
j++){nextVArr[i][j]=-1;
fvArr=newint*[f_num];
fnArr=newGLfloat*[f_num];
ftArr=newint*[f_num];
f_num;
fvArr[i]=newint[3];
fnArr[i]=newGLfloat[3];
ftArr[i]=newint[10];
if(!
TOroon0
⅛u--s)u-IUe①」ω6u⅛s-
)
IH型⅛二(5-HO」①U=S)七
宀
+^±
3hξ-=,ej<
>
S2U三==」」<
ZJh≡-=,ej<
SAACAAAALSAAU-S
⅛u=s)uωIUe①」ω6u⅛s-
型⅛->
Hoj①U=S)七
(φu=sφ=μηφU=φ6)φ=fOHEE-OHΨ∣OOH=IU一©
——<
=φu=s6u⅛s宀
^)七X①
=PU①VV--=GLUeUedO--VVIn8
)(+±
°
LV二0上I--)」OJ
HgqQEnUH曰〔L&
Enurolx①Ujz>
lH≡L7Lunu,Ej<
J>
二L-H≡L7enu,Ej<
七二++「oLV「oH「-U二」OJ
ZEnUH曰〔VLEFlUKUOlXeUjzdH曰(τ7LEnu,Ej<
二τ7H≡τ7LEnu,Ej<
七二+±
OLV一O上IU二」OJ
QEnUHcm=ψi,ejv>
jZIUnU“三N兰」」<
」=EnUHo=ψi,ej∀>
j
J⅛>
=EEnUAEnUAAEnUAALSAAU一
if(vfArr[num3-1][i]==-1){vfArr[num3-1][i]=kk;
nextVArr[num3-1][i]=num1;
break;
kk++;
return0;
//计算面法向
voidnomal(point3p){/*矢量的归一化*///doublesqrt();
floatd=0.0;
inti;
for(i=0;
i++)
d+=p[i]*p[i];
d=sqrt(d);
if(d>
0.0)
p[i]/=d;
voidgetFaceNormal(point3A,point3B,point3C){
x[0]=
C[0]-
A[0];
x[1]=
C[1]-
A[1];
x[2]=
C[2]-
A[2];
y[0]=
A[0]-
B[0];
y[1]=
A[1]-
B[1];
y[2]=
A[2]-
B[2];
point3
v;
v[0]=x[1]*y[2]-x[2]*y[1];
v[1]=x[2]*y[0]-x[0]*y[2];
v[2]=x[0]*y[1]-x[1]*y[0];
nomal(v);
glNormal3fv(v);
voidLaplacian(){
for(intnum=0;
num<
num++){intm=0;
//求得点的邻接面数
if(nextVArr[num][i]!
=-1){
m++;
}else{
break;
point3v0;
v0[i]=0;
v0[0]+=vArr[nextVArr[num][i]-1][0];
v0[1]+=vArr[nextVArr[num][i]-1][1];
v0[2]+=vArr[nextVArr[num][i]-1][2];
if(m!
=0){
v0[i]/=m;
l[0]=v0[0]-vArr[num][0];
l[1]=v0[1]-vArr[num][1];
l[2]=v0[2]-vArr[num][2];
vNewArr[num][0]=vArr[num][0]+l[0]*0.3;
vNewArr[num][1]=vArr[num][1]+l[1]*0.3;
vNewArr[num][2]=vArr[num][2]+l[2]*0.3;
vArr[i][0]=vNewArr[i][0];
vArr[i][1]=vNewArr[i][1];
vArr[i][2]=vNewArr[i][2];
voidinit(void)
);
/*initialviewerlocation*/
getLineNum("
H:
\\kitten_noisy.obj"
readfile("
doubleviewer[]={0.0,0.0,8.0};
GLfloatmat_specular[]={1.0,1.0,1.0,1.0};
GLfloatmat_shininess[]={50.0};
//材料的镜面指数,其值越大越精细
GLfloatlight_position[]={1.0,1.0f,1.0,0.0};
GLfloatwhite_light[]={1.0,1.0,1.0,1.0};
GLfloatlmodel_ambient[]={0.1,0.1,0.1,1.0};
glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_SMOO)T;
H
glMaterialfv(GL_FRON,TGL_SPECULA,mRat_specular);
glMaterialfv(GL_FRON,TGL_SHININES,Smat_shininess);
glLightfv(GL_LIGHT0,GL_POSITIO,Nlight_position);
//光源位置
glLightfv(GL_LIGHT0,GL_DIFFUS,Ewhite_light);
//漫反射光源
glLightfv(GL_LIGHT0,GL_SPECULA,wRhite_light);
//镜面反射光源
glLightModelfv(GL_LIGHT_MODEL_AMBIE,lNmTodel_ambient);
//环境光源//glEnable(glMaterialf);
glEnable(GL_LIGHTING);
//启动光照
glEnable(GL_LIGHT0);
//启用0度光源
glEnable(GL_DEPTH_TES);
T//启动深度测试
/*
glShadeModel(GL_SMOOTH);
//
EnableSmoothShading
glClearColor(0.0f,0.0f,0.0f,0.5f);
黑色背景
glClearDepth(1.0f);
//深度缓冲区设置
glEnable(GL_DEPTH_TEST);
允许深度测试
glDepthFunc(GL_LEQUAL);
//定义深度测试类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
ReallyNicePerspectiveCalculation
*/
//设置观察
-1],vArr[fvArr[i][2]
voiddisplay(void)
glClear(GL_COLOR_BUFFER_B|ITGL_DEPTH_BUFFER_)B;
ITglLoadIdentity();
gluLookAt(viewer[0],viewer[1],viewer[2],0.0,0.0,0.0,0.0,1.0,0.0);
的位置
glRotatef(theta[0],1.0,0.0,0.0);
glRotatef(theta[1],0.0,1.0,0.0);
//glRotatef(theta[2],0.0,0.0,1.0);
glTranslatef(Tran[0],Tran[1],Tran[2]);
glScalef(sca,sca,sca);
//glPolygonMode(GL_FRONT_AND_BACK,GLU_FILL);
glBegin(GL_TRIANGLE)S;
//getFaceNormals();
i<
f_num;
getFaceNormal(vArr[fvArr[i][0]-1],vArr[fvArr[i][1]
-1]);
glVertex3f(vArr[fvArr[i][0]-1][0],vArr[fvArr[i][0]-1][1],vArr[fvArr[i][0]-1][2]);
glVertex3f(vArr[fvArr[i][1]-1][0],vArr[fvArr[i][1]-1][1],vArr[fvArr[i][1]-1][2]);
glVertex3f(vArr[fvArr[i][2]-1][0],vArr[fvArr[i][2]-1][1],vArr[fvArr[i][2]-1][2]);
glEnd();
/*glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_POINTS);
glColor3f(1.0,1.0,1.0);
for(inti=0;
glVertex3fv(vArr[i]);
glNormal3fv(fnArr[i]);
glFlush();
//强制绘图glutSwapBuffers();
voidreshape(intw,inth)
glViewport(0,0,(GLsizei)w,(GLsizei)h);
//视口设置
glMatrixMode(GL_PROJECTIO);
NglLoadIdentity();
if(w<
=h)//描绘了两种不同情况下的平行修剪空间glOrtho(-0.6,0.6,-0.6*(GLfloat)h/(GLfloat)w,0.6*(GLfloat)h/(GLfloat)w,
-10.0,10.0);
elseglOrtho(-0.6*(GLfloat)w/(GLfloat)h,0.6*(GLfloat)w/(GLfloat)h,-0.6,0.6,-10.0,10.0);
glMatrixMode(GL_MODELVIE);
W
#defineGLUT_WHEEL_U3P//定义滚轮操作
#defineGLUT_WHEEL_DO4WN
voidmouse(intbtn,intstate,intx,inty){
if(btn==GLUT_LEFT_BUTT&
O&
Nstate==GLUT_DOW){NLaplacian();
if(btn==GLUT_MIDDLE_BUTT&
sNtate==GLUT_DOW)aNxis=0;
if(btn==GLUT_RIGHT_BUTT&
Nstate==GLUT_DOW)aNxis=1;
theta[axis]+=2.0;
if(theta[axis]>
360.0)theta[axis]-=360.0;
display();
voidkeys(unsignedcharkey,intx,inty){
if(key=='
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 图形学 实验 报告