图形学实验四:地理划分画球算法实验

更新时间:2023-06-25 02:53:19 阅读: 评论:0

太原工业学院计算机工程系
实 验 报 告
课程名称
计算机图形学
班级
1320541
实验日期
2015年6月4日星期四
姓    名
刘创
学号
37
实验成绩
实验名称
          实验四 地理划分画球算法
1)理解球边表和面表算法
2)理解双缓冲的算法
3)理解mfc作用原理
VC++6.0基于MFC
陈庚大将实
              利用mfc绘制地理球
部分重要代码截图:
雅思作文模板(用适当的形式表达算法设计思想与算法实现步骤)
逻辑题
实验过程中没有出现太大的问题
实验结果展示如下:
                      地理球
(详细记录在调试过程中出现的问题及解决方法。记录实验运行结果)
1)通过本次实验,了解到了mfc的最基本知识,发现自己学习mfc任重而道远,在前行的路上还有很多学习的地方。
2)实践是检验真理的唯一标准
3)动手能力需要再次提高
4)算法思想要与时俱进,要多学习算法
(对实验结果进行分析,实验心得体会及改进意见)
//OnDraw函数
void CTestView::OnDraw(CDC* pDC)
{
    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    // TODO: add draw code for native data here
    DoubleBuffer();   
}
void CTestView::ReadVertex()//读入顶点坐标我为你唱首歌
{
    int gAlpha=4,gBeta=4;//面片夹角迎新横幅
    N1=180/gAlpha,N2=360/gBeta;//N1为纬度区域,N2为经度区域
    V=new CP3[(N1-1)*N2+2];//V为球的顶点
    //纬度方向除南北极点外有"N1-1"个点,"2"代表南北极两个点
    double gAlpha1,gBeta1,r=300;//r为球体半径
    //计算北极点坐标
330日元    V[0].x=0,V[0].y=r,V[0].z=0;
    //按行循环计算球体上的点坐标
    for(int i=0;i<N1-1;i++)
都江堰是谁设计的    {
        gAlpha1=(i+1)*gAlpha*PI/180;
        for(int j=0;j<N2;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;   
}
void CTestView::ReadFace()//读入面表
{
    //设置二维动态数组
    F=new CFace *[N1];//设置行
    for(int n=0;n<N1;n++)
        F[n]=new CFace[N2];//设置列
    for(int j=0;j<N2;j++)//构造北极三角形面片
    {
        int tempj=j+1;
        if(tempj==N2) tempj=0;//面片的首尾连接
        int NorthIndex[3];//北极三角形面片索引号数组
        NorthIndex[0]=0;
        NorthIndex[1]=j+1;
        NorthIndex[2]=tempj+1;
        F[0][j].SetNum(3);
        for(int k=0;k<F[0][j].vN;k++)
            F[0][j].vI[k]=NorthIndex[k];
    }
    for(int i=1;i<N1-1;i++)//构造球面四边形面片
    {
        for(int j=0;j<N2;j++)
        {
            int tempi=i+1;
            int tempj=j+1;
            if(tempj==N2) tempj=0;
            int BodyIndex[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(int k=0;k<F[i][j].vN;k++)
                F[i][j].vI[k]=BodyIndex[k];
        }
    }
    for(j=0;j<N2;j++)//构造南极三角形面片
    {
        int tempj=j+1;
        if(tempj==N2) tempj=0;
        int SouthIndex[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(int k=0;k<F[N1-1][j].vN;k++)
            F[N1-1][j].vI[k]=SouthIndex[k];
    }
}
void CTestView::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];
}
void CTestView::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;
    ScreenP.x=d*ViewP.x/ViewP.z;//屏幕二维坐标系
    ScreenP.y=d*ViewP.y/ViewP.z;
}
void CTestView::DoubleBuffer()//双缓冲
{
    CDC* pDC=GetDC();
    CRect rect;//定义客户区
    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);//屏幕中心为原点
    CDC MemDC;//内存DC
    CBitmap NewBitmap,*pOldBitmap;//内存中承载图像的临时位图
    MemDC.CreateCompatibleDC(pDC);//建立与屏幕pDC兼容的MemDC
    NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容位图
    pOldBitmap=MemDC.SelectObject(&NewBitmap); //将兼容位图选入MemDC
    MemDC.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();//删除位图
    ReleaDC(pDC);//释放DC
}
void CTestView::DrawObject(CDC *pDC)//绘制球面线框模型
{
        CP2 Point3[3],t3;//南北极顶点数组
    CP2 Point4[4],t4;//球体顶点数组
    for(int i=0;i<N1;i++)
    {
        for(int j=0;j<N2;j++)
        {
            CVector ViewVector(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)//三角形面片
                {
                    for(int m=0;m<F[i][j].vN;m++)
                    {
                        PerProject(V[F[i][j].vI[m]]);
                        Point3[m]=ScreenP;
                    }
                    for(int n=0;n<3;n++)
                    {
                        if(0==n)
                        {
                            pDC->MoveTo(Point3[n].x,Point3[n].y);
                            t3=Point3[n];
                        }
                        el
                            pDC->LineTo(Point3[n].x,Point3[n].y);   
                    }
                    pDC->LineTo(t3.x,t3.y);//闭合多边形
                }
                el//四边形面片
                {
                    for(int m=0;m<F[i][j].vN;m++)
                    {
                        PerProject(V[F[i][j].vI[m]]);
                        Point4[m]=ScreenP;
                    }
                    for(int n=0;n<4;n++)
                    {
                        if(0==n)
                        {
                            pDC->MoveTo(Point4[n].x,Point4[n].y);
                            t4=Point4[n];
                        }
                        el
                            pDC->LineTo(Point4[n].x,Point4[n].y);   
                    }
                    pDC->LineTo(t4.x,t4.y);//闭合多边形
                }
            }   
        }   
    }
}
void CTestView::OnTimer(UINT nIDEvent)
{
    // TODO: Add your message handler code here and/or call default
    Alpha=5;Beta=5;
    tran.RotateX(Alpha);
    tran.RotateY(Beta);
    Invalidate(FALSE);
    CView::OnTimer(nIDEvent);
}
BOOL CTestView::OnEraBkgnd(CDC* pDC)//禁止背景刷新
{
    // TODO: Add your message handler code here and/or call default
    return TRUE;
}
void CTestView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
    // TODO: Add your specialized code here and/or call the ba class
    ReadVertex();
    ReadFace();
    tran.SetMat(V,(N1-1)*N2+2);
    InitParameter();
}
void CTestView::OnExit()
{
    // TODO: Add your command handler code here
    exit(0);
}
void CTestView::OnMenuitem32799()
咖啡学习{
    // TODO: Add your command handler code here
    SetTimer(1,100,NULL);
}
void CTestView::OnMenuitem32800()
{
    // TODO: Add your command handler code here
    KillTimer(1);
}

本文发布于:2023-06-25 02:53:19,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1053637.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:实验   算法   面片   数组   屏幕
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图