《计算机图形学》 课程学习报告
;
项目题目:
圆柱面图像纹理映射算法.
目录
一、项目描述....................................................................................................................................1 1.1圆柱面的建立和二维图像纹理的绑定..............................................................................1
1.2坐标系的建立......................................................................................................................1 二、项目需求....................................................................................................................................1 2.1 几何构造的原理.................................................................................................................1 2.2、动画的设计 .................................................................................................................... 2 2.3 纹理的设计........................................................................................................................ 2
2.3.1 纹理映射的原理 ......................................................................................................... 2 2.3.2 纹理定义 ..................................................................................................................... 2 三、项目设计....................................................................................................................................3 3.1、窗口设计以及各项功能的实现..................................................................................... 3 3.1.1 窗口设计函数............................................................................................................. 3
3.1.2 点表函数 ..................................................................................................................... 4 3.1.3 面表函数 ..................................................................................................................... 4 3.1.4 绘制圆柱函数 ............................................................................................................. 6 3.1.5 透视变换函数 ............................................................................................................. 8 3.1.6 读入纹理函数 ............................................................................................................. 8 3.1.7 背景函数 ..................................................................................................................... 9 3.1.8 时间函数....................................................................................................................9 3.1.9 动画控制函数............................................................................................................10 四、项目效果..................................................................................................................................10 4.1构造图形分析以及坐标系变换的效果.....................................错误!未定义书签。
五、项目总结..................................................................................................................................11 六、参考文献..................................................................................................................................12
.
一、项目描述
1.1、圆柱的建立和二维图像纹理的绑定
以屏幕客户区中心为体心建立圆柱面的几何模型。读入二维位图图像纹理,将纹理绑定到圆柱上。使用材质慢反射率设置纹理颜色,光源颜色设置为白色。使用Phong明暗处理绘制光照纹理圆柱面动画
1.2、坐标系的建立
1>、自定义屏幕三维左手坐标,原点位于客户区中心,x轴水平向右为正,
y轴垂直向上为正,z轴指向屏幕内部,
2>、建立三维用户右手坐标系{O;x,y,z},原点O位于客户区中心,x轴水平向右,y垂直向上,z轴指向读者。
二、项目需求 2.1、几何构造的原理
圆柱面采用平面四边形小面逼近,需要根据周向相邻2个小面的法矢量计算平均法矢量。对于索引号(i,j)的顶点,其相邻顶点的索引号如图所示。图中箭头所示为每个小面的边矢量,俩个边矢量的叉积得到小面的法矢量Ni。
Ni小面的平均法矢量N的计算公式为N=
1Nii0i01
i,j+1 i,j
i,j-1
i-1,j+1 i-1,j 圆柱面平均法矢量的计算
i-1,j-1 2.2、动画的设计
实现动画的函数
void CMy123054212View::OnPlay()
1
.
{
// TODO: Add your command handler code here bPlay=bPlay?FALSE:TRUE; if(bPlay)//设置定时器 SetTimer(1,150,NULL); Else
KillTimer(1); }
设定动画时间
void CTestView::OnTimer(UINT nIDEvent)//动画时间函数 {
// TODO: Add your message handler code here and/or call default Beta=5;
tran.RotateY(Beta); Invalidate(FALSE); CView::OnTimer(nIDEvent); }
2.3、纹理的设计 2.3.1 纹理映射的原理
使用MFC的资源标签页加载二维图像纹理,DDB位图的标识取为IDB_TEXTURE。将纹理读入二维数组中,将纹理图像绑定到圆柱面的侧面网格顶点上。将图像纹理的颜色值作为材质漫反射率和环境光反射率,镜面反射光设置为白光,使用Phong明暗处理绘制光照纹理圆柱面。 2.3.2 纹理的定义
在CTestView类内添加成员函数ReadVertex(),将纹理绑定到圆柱面侧面的顶点上,CT2类定义了纹理坐标的(u,v)。由于底面和顶面采用三角形网格逼近,所以使用CT2类定义了Texture4和Texture3纹理数组。圆柱的侧面使用周向平均法矢量计算光照。填充底面顶面的三角形面片时,进行了特殊处理。然后添加ReadImage()读入纹理。
2
.
三、项目设计
3.1、窗口设计以及各项功能的实现 3.1.1窗口设计函数
BOOL CMy123054212App::InitInstance()
{// The one and only window has been initialized, so show and update it. m_pMainWnd->ShowWindow(SW_MAXIMIZE);
m_pMainWnd->SetWindowText(\"1234054212刘美艳\"); m_pMainWnd->UpdateWindow(); return TRUE; }
3.1.2、点表函数
void CMy123054212View::ReadVertex()//点表 {
double r=144;//圆柱底面半径 h=500;//圆柱的高 cTheta=10;//周向夹角 cNum=10;//纵向间距
N1=360/cTheta;//N1周向网格数 N2=Round(h/cNum);//N2纵向网格数 V=new CP3[N1*(N2+1)+2];//顶点动态数组 T=new CT2[N1*(N2+1)+2];//纹理动态数组 N=new CVector[N1*(N2+1)+2];//法矢量动态数组 double cTheta1,cNum1;
V[0].x=0;V[0].y=0;V[0].z=0;//底面中心 T[0].u=0;T[0].v=0;//闲置 for(int i=0;i 3 . for(int j=0;j V[i*N1+j+1].z=r*sin(cTheta1); T[i*N1+j+1].u=(2*PI-cTheta1)/(2*PI)*(bmp.bmWidth-1);//u(0->1) T[i*N1+j+1].v=V[i*N1+j+1].y/h*(bmp.bmHeight-1);//v(0->1) } } V[N1*(N2+1)+1].x=0;V[N1*(N2+1)+1].y=h;V[N1*(N2+1)+1].z=0;//顶面中心T[N1*(N2+1)+1].u=0;T[N1*(N2+1)+1].v=0;//闲置 } 3.1.3、面表函数 void CMy123054212View::ReadFace()//面表 { //设置二维动态数组 F=new CFace *[N2+2];//纵向 for(int n=0;n if(N1==tempj) tempj=0;//面片的首尾连接 int BottomIndex[3];//底部三角形面片索引号数组 BottomIndex[0]=0; BottomIndex[1]=j+1; BottomIndex[2]=tempj+1; F[0][j].SetNum(3); 4 . for(int k=0;k if(N1==tempj) tempj=0; int BodyIndex[4];//圆柱体四边形面片索引号数组 BodyIndex[0]=(i-1)*N1+j+1; BodyIndex[1]=(tempi-1)*N1+j+1; BodyIndex[2]=(tempi-1)*N1+tempj+1; BodyIndex[3]=(i-1)*N1+tempj+1; F[i][j].SetNum(4); for(int k=0;k if(N1==tempj) tempj=0; int TopIndex[3];//顶部三角形面片索引号数组 TopIndex[0]=N1*i+1; TopIndex[1]=N1*(i-1)+tempj+1; TopIndex[2]=N1*(i-1)+j+1; F[N2+1][j].SetNum(3); 5 . for(int k=0;k void CMy123054212View::DrawObject(CDC *pDC)//绘制圆柱面 { CalNormal(); CZBuffer *zbuf=new CZBuffer;//申请内存 zbuf->InitDeepBuffer(800,800,1000);//初始化深度缓冲器 CPi3 Point3[3];//底面与顶面三角形顶点数组 CT2 Texture3[3];//底面与顶面三角形纹理数组 CVector Normal3[3];//底面与顶面三角形法矢量数组 CPi3 Point4[4];//侧面四边形顶点数组 CT2 Texture4[4];//侧面四边形纹理数组 CVector Normal4[4];//侧面四边形法矢量数组 for(int i=0;i F[i][j].SetFaceNormal(V[F[i][j].vI[0]],V[F[i][j].vI[1]],V[F[i][j].vI[2]]);//计算小面片法矢量 F[i][j].fNormal.Normalize();//单位化法矢量 if(Dot(ViewVector,F[i][j].fNormal)>=0) { if(3==F[i][j].vN)//处理三角形面片 { 6 . for(int m=0;m Point3[m]=ScreenP; Normal3[m]=F[i][j].fNormal; } double tempj=j+1;//对三角形面片进行特殊处理 Texture3[0].u=cTheta*(j+0.5)/360.0;Texture3[0].v=0.0; Texture3[1].u=cTheta*(j+0.5)/360.0;Texture3[1].v=0.0; Texture3[2].u=cTheta*tempj/360.0; Texture3[2].v=0.0; zbuf->SetPoint(Point3,Normal3,Texture3,3);//初始化 zbuf->CreateBucket();//创建桶表 zbuf->CreateEdge();//创建边表 zbuf->Phong(pDC,ViewPoint,pLight,pMaterial,Image);//填充三角形 zbuf->ClearMemory(); } else//处理四边形面片 { for(int m=0;m Normal4[m]=N[F[i][j].vI[m]]; Texture4[m]=T[F[i][j].vI[m]]; } if(N1-1==j)//消除图像纹理的接缝 { Texture4[2].u=0.0; 7 . Texture4[3].u=0.0; } zbuf->SetPoint(Point4,Normal4,Texture4,4);//初始化 zbuf->CreateBucket();//创建桶表 zbuf->CreateEdge();//创建边表 zbuf->Phong(pDC,ViewPoint,pLight,pMaterial,Image);//填充四边形 zbuf->ClearMemory(); } } } } delete zbuf; } 3.1.5、透视变换函数 void CMy123054212View::PerProject(CP3 P)//透视变换 { CP3 ViewP; ViewP.x=P.x*k[3]-P.z*k[1];//观察坐标系三维坐标 ViewP.y=-P.x*k[8]+P.y*k[2]-P.z*k[7]; ViewP.z=-P.x*k[6]-P.y*k[4]-P.z*k[5]+R; ViewP.c=P.c; ScreenP.x=d*ViewP.x/ViewP.z;//屏幕坐标系三维坐标 ScreenP.y=Round(d*ViewP.y/ViewP.z); ScreenP.z=Far*(1-Near/ViewP.z)/(Far-Near); ScreenP.c=ViewP.c; } 3.1.6、读入纹理 void CMy123054212View::ReadImage()//读入纹理 { 8 . CBitmap NewBitmap; NewBitmap.LoadBitmap(IDB_TEXTURE);//调入DDB位图 NewBitmap.GetBitmap(&bmp);//将CBitmap的信息保存到Bitmap结构体中 int nbytesize=bmp.bmWidthBytes*bmp.bmHeight; im=new BYTE[nbytesize]; NewBitmap.GetBitmapBits(nbytesize,(LPVOID)im); Image=new COLORREF*[bmp.bmHeight]; for(int n1=0;n1 delete []im; } 3.1.7、背景函数 BOOL CMy123054212View::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return TRUE; } 3.1.8、时间函数 void CMy123054212View::OnTimer(UINT nIDEvent) 9 . { // TODO: Add your message handler code here and/or call default Beta=5; tran.RotateY(Beta); Invalidate(FALSE); CView::OnTimer(nIDEvent); } 3.1.9、动画控制函数 void CMy123054212View::OnUpdatePlay(CCmdUI* pCmdUI) { // TODO: Add your command update UI handler code here if(bPlay) { pCmdUI->SetCheck(TRUE); pCmdUI->SetText(\"停止\"); } else { pCmdUI->SetCheck(FALSE); pCmdUI->SetText(\"开始\"); } } 四、项目效果 4.1构造图形分析以及坐标系变换的效果 10 . 五、项目总结 本项目将一幅位图映射到圆柱面上,并进行了光照计算。由于圆柱面侧面的展开图是长方形,如果取得图像大小为侧面展开图的大小,则圆柱面上的像素与图像上的像素有一一对应关系。本项目在点表中进行图像纹理绑定。对于单幅图像映射,一般在点表中绑定;对于多幅图像映射,一般在面表中绑定。侧面四边形顶点的法矢量取为周向2个表面的平均法矢量。圆柱面试闭合的二次曲面,这要求对图 11 . 像纹理闭合处进行特殊处理,处理方法见DrawObject()函数。 六、参考文献 计算机图形学实践教程(第二版 孔令德) 计算机图形学基础教程(第二版 孔令德) 12 因篇幅问题不能全部显示,请点此查看更多更全内容