1课程名称计算机图形学班级1320541实验日期2015年6月4日星期四姓名刘创学号37实验成绩实验名称实验四地理划分画球算法实验目的及要求1)理解球边表和面表算法2)理解双缓冲的算法3)理解mfc作用原理实验环境VC++6.0基于MFC实验内容利用mfc绘制地理球算法描述及实验步骤部分重要代码截图:太原工业学院计算机工程系实验报告2(用适当的形式表达算法设计思想与算法实现步骤)调试过程及实验结果实验过程中没有出现太大的问题实验结果展示如下:地理球(详细记录在调试过程中出现的问题及解决方法。记录实验运行结果)总结1)通过本次实验,了解到了mfc的最基本知识,发现自己学习mfc任重而道远,在前行的路上还有很多学习的地方。2)实践是检验真理的唯一标准3)动手能力需要再次提高4)算法思想要与时俱进,要多学习算法(对实验结果进行分析,实验心得体会及改进意见)3附录//OnDraw函数voidCTestView::OnDraw(CDC*pDC){CTestDoc*pDoc=GetDocument();ASSERT_VALID(pDoc);//TODO:adddrawcodefornativedatahereDoubleBuffer();}voidCTestView::ReadVertex()//读入顶点坐标{intgAlpha=4,gBeta=4;//面片夹角N1=180/gAlpha,N2=360/gBeta;//N1为纬度区域,N2为经度区域V=newCP3[(N1-1)*N2+2];//V为球的顶点//纬度方向除南北极点外有N1-1个点,2代表南北极两个点doublegAlpha1,gBeta1,r=300;//r为球体半径//计算北极点坐标V[0].x=0,V[0].y=r,V[0].z=0;//按行循环计算球体上的点坐标for(inti=0;iN1-1;i++){gAlpha1=(i+1)*gAlpha*PI/180;for(intj=0;jN2;j++){gBeta1=j*gBeta*PI/180;V[i*N2+j+1].x=r*sin(gAlpha1)*sin(gBeta1);V[i*N2+j+1].y=r*cos(gAlpha1);V[i*N2+j+1].z=r*sin(gAlpha1)*cos(gBeta1);}}//计算南极点坐标V[(N1-1)*N2+1].x=0,V[(N1-1)*N2+1].y=-r,V[(N1-1)*N2+1].z=0;}voidCTestView::ReadFace()//读入面表{//设置二维动态数组F=newCFace*[N1];//设置行for(intn=0;nN1;n++)F[n]=newCFace[N2];//设置列for(intj=0;jN2;j++)//构造北极三角形面片{inttempj=j+1;if(tempj==N2)tempj=0;//面片的首尾连接intNorthIndex[3];//北极三角形面片索引号数组NorthIndex[0]=0;NorthIndex[1]=j+1;NorthIndex[2]=tempj+1;F[0][j].SetNum(3);for(intk=0;kF[0][j].vN;k++)F[0][j].vI[k]=NorthIndex[k];}4附录for(inti=1;iN1-1;i++)//构造球面四边形面片{for(intj=0;jN2;j++){inttempi=i+1;inttempj=j+1;if(tempj==N2)tempj=0;intBodyIndex[4];//球面四边形面片索引号数组BodyIndex[0]=(i-1)*N2+j+1;BodyIndex[1]=(tempi-1)*N2+j+1;BodyIndex[2]=(tempi-1)*N2+tempj+1;BodyIndex[3]=(i-1)*N2+tempj+1;F[i][j].SetNum(4);for(intk=0;kF[i][j].vN;k++)F[i][j].vI[k]=BodyIndex[k];}}for(j=0;jN2;j++)//构造南极三角形面片{inttempj=j+1;if(tempj==N2)tempj=0;intSouthIndex[3];//南极三角形面片索引号数组SouthIndex[0]=(N1-2)*N2+j+1;SouthIndex[1]=(N1-1)*N2+1;SouthIndex[2]=(N1-2)*N2+tempj+1;F[N1-1][j].SetNum(3);for(intk=0;kF[N1-1][j].vN;k++)F[N1-1][j].vI[k]=SouthIndex[k];}}voidCTestView::InitParameter()//透视变换参数初始化{k[1]=sin(PI*Theta/180);k[2]=sin(PI*Phi/180);k[3]=cos(PI*Theta/180);k[4]=cos(PI*Phi/180);k[5]=k[2]*k[3];k[6]=k[2]*k[1];k[7]=k[4]*k[3];k[8]=k[4]*k[1];ViewPoint.x=R*k[6];ViewPoint.y=R*k[4];ViewPoint.z=R*k[5];}voidCTestView::PerProject(CP3P)//透视变换{CP3ViewP;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;5附录ScreenP.x=d*ViewP.x/ViewP.z;//屏幕二维坐标系ScreenP.y=d*ViewP.y/ViewP.z;}voidCTestView::DoubleBuffer()//双缓冲{CDC*pDC=GetDC();CRectrect;//定义客户区GetClientRect(&rect);//获得客户区的大小pDC-SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系pDC-SetWindowExt(rect.Width(),rect.Height());//设置窗口范围pDC-SetViewportExt(rect.Width(),-rect.Height());//x轴水平向右,y轴垂直向上pDC-SetViewportOrg(rect.Width()/2,rect.Height()/2);//屏幕中心为原点CDCMemDC;//内存DCCBitmapNewBitmap,*pOldBitmap;//内存中承载图像的临时位图MemDC.CreateCompatibleDC(pDC);//建立与屏幕pDC兼容的MemDCNewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容位图pOldBitmap=MemDC.SelectObject(&NewBitmap);//将兼容位图选入MemDCMemDC.FillSolidRect(&rect,pDC-GetBkColor());//按原来背景填充客户区,否则是黑色MemDC.SetMapMode(MM_ANISOTROPIC);//MemDC自定义坐标系MemDC.SetWindowExt(rect.Width(),rect.Height());MemDC.SetViewportExt(rect.Width(),-rect.Height());MemDC.SetViewportOrg(rect.Width()/2,rect.Height()/2);DrawObject(&MemDC);pDC-BitBlt(-rect.Width()/2,-rect.Height()/2,rect.Width(),rect.Height(),&MemDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY);//将内存位图拷贝到屏幕MemDC.SelectObject(pOldBitmap);//恢复位图NewBitmap.DeleteObject();//删除位图ReleaseDC(pDC);//释放DC}voidCTestView::DrawObject(CDC*pDC)//绘制球面线框模型{CP2Point3[3],t3;//南北极顶点数组CP2Point4[4],t4;//球体顶点数组for(inti=0;iN1;i++){for(intj=0;jN2;j++){CVectorViewVector(V[F[i][j].vI[0]],ViewPoint);//面的视矢量ViewVector=ViewVector.Normalize();//单位化视矢量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(intm=0;mF[i][j].vN;m++){PerProject(V[F[i][j].vI[m]]);Point3[m]=ScreenP;}for(intn=0;n3;n++){if(0==n){pDC-MoveTo(Point3[n].x,Point3[n].y);t3=Point3[n];}elsepDC-LineTo(Point3[n].x,Point3[n].y);}pDC-LineTo(t3.x,t3.y);//闭合多边形}else//四边形面片{for(intm=0;mF[i][j].vN;m++){PerProject(V[F[i][j].vI[m]]);Point4[m]=ScreenP;}for(intn=0;n4;n++){if(0==n){pDC-MoveTo(Point4[n].x,Point4[n].y);t4=Point4[n];}elsepDC-LineTo(Point4[n].x,Point4[n].y);}pDC-LineTo(t4.x,t4.y);//闭合多边形}}}}}voidCTestView::OnTimer(UINTnIDEvent){//TODO:Addyourmessagehandlercodehereand/orcalldefaultAlpha=5;Beta=5;tran.RotateX(Alpha);tran.RotateY(Beta);Invalidate(FALSE);7附录CView::OnTimer(nIDEvent);}BOOLCTestView::OnEraseBkgnd(CDC*pDC)//禁止背景刷新{//TODO:Addyourmessagehandlercodehereand/orcalldefaultreturnTRUE;}voidCTestView::OnInitialUpdate(){CView::OnInitialUpdate();//TODO:Addyourspecializedcodehereand/orcallthebaseclassReadVertex();ReadFace();tran.SetMat(V,(N1-1)*N2+2);InitParameter();}voidCTestView::OnExit(){//TODO:Addyourcommandhandlercodehereexit(0);}voidCTestView::OnMenuitem32799(){//TODO:A