计算机图形学实验报告

河南理工大学测绘学院

《计算机图形学》实验报告

学号             

 


姓名            

 


成绩              

 


评语:

 

交报告日期:  20##年 6 月 25 日


实验项目一:图形学光栅化算法验证实验

实验日期:2012 年6 月 5日

一、实验目的:

1、加强对直线、圆的光栅化算法的理解。工程中的绘图函数不允许使用微软MFC类库CDC类提供的方法,必须使用图形学教材上的光栅化算法。

2、掌握基本图形系统交互设计方法。

3、熟悉windows程序的基本消息处理。

二、你认为实验中的较好的设计或代码:


void CGIS1002_10View::Breshenham_Line(CPoint pt1, CPoint pt2, CDC * pDC)

{

      int dx,dy,x,y,d,d1,d2,inc,tmp;

      dx=pt2.x - pt1.x ;

      dy=pt2.y - pt1.y;

      CPoint b;

      if(dx * dy>=0)          //准备x,y单位的递变值

             inc = 1;

      else

             inc = -1;

      if(abs(dx)>abs(dy))

      {

             if(dx<0)           //将2a,3a区域的直线变换到1a,4a区域

             {

                    tmp = pt2.x;pt2.x = b.x;b.x = tmp;

                    tmp = pt2.y;pt2.y = b.y;b.y = tmp;

                    dx = -dx;dy=-dy;

             }

         if(dy<0)………………

         dy=-dy;………………

             d = 2*dy - dx;

             d1 = 2*dy;

             d2 = 2*(dy - dx);

             x = pt1.x;

             y = pt1.y;

             pDC->SetPixel(x,y,RGB(0,0,255));

             while(x <  pt2.x)

             {

                    x++;

                    if(d<0)

                           d+=d1;

                    else

                    {

                           y+=inc;

                           d+=d2;

                    }

             pDC->SetPixel(x,y,RGB(0,0,255));

             }

      }

      else

      {

             if(dy<0)           //将3b,4b区域的直线变换到1b,2b区域

             {

                    tmp = pt2.x;pt2.x = b.x;b.x = tmp;

                    tmp = pt2.y;pt2.y = b.y;b.y = tmp;

                    dx = -dx;dy=-dy;

             }

         if(dx<0) ………………

         dx=-dx;……………….

          d = 2*dx - dy;

             d1 = 2*dx;

             d2 = 2*(dx - dy);

             x = pt1.x;

             y = pt1.y;

             pDC->SetPixel(x,y,RGB(0,0,255));

             while(y<  pt2.y)

             {

                    y++;

                    if(d<0)

                           d+=d1;

                    else

                    {

                           x+=inc;

                           d+=d2;

                    }

             pDC->SetPixel(x,y,RGB(0,0,255));

             }

      }

      ReleaseDC(pDC);

}

上述代码为直线的Breshenham画线算法,它是计算机图形学领域使用最广泛的直线生成算法。它的基本原理是:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。其中的①②③④将直线画线的象限区域范围扩大了,如上图所示。


三、实验总结:

通过本次试验,我发现了这种画线算法的优越性,但是由于对代码本身的不理解以及对类的知识点的遗忘,所以在改书中代码时费了很大功夫。另外,通过本次试验我加强了对直线、圆的光栅化算法的理解,基本掌握了基本图形系统交互设计方法,熟悉了windows程序的基本消息处理,基本完成实验目的。

实验项目二: 基于OpenGL的图形学编程实验

实验日期:2012 年 6 月 13日

一、实验目的:

1、掌握Windows编程环境中的OpenGL程序框架设计和一般的OpenGL绘图环境设置和三维场景绘制步骤。

2、掌握基本的OpenGL API应用函数的使用和参数设置。

二、你认为实验中的较好的设计或代码:

void CGIS1002_10View::ReadTexture()

{

      CString strCurrentPath = ((CGIS1002_10App*)AfxGetApp())->m_pszHelpFilePath;

      strCurrentPath.TrimLeft();

      strCurrentPath.TrimRight();

      int pos = strCurrentPath.ReverseFind('\\');

      strCurrentPath = strCurrentPath.Left(pos-2);

      pos = strCurrentPath.ReverseFind('\\');

      strCurrentPath = strCurrentPath.Left(pos+1);

      CString pszFileName = strCurrentPath+"b.bmp";

      CFile myFile;

      CFileException fileException;

      if ( !myFile.Open( pszFileName, CFile::modeRead, &fileException ) )

      {

             TRACE( "Can't open file %s, error = %u\n",

                pszFileName, fileException.m_cause );

      }

     

      HDIB hdib = ::ReadDIBFile(myFile);

      LPSTR lp = (LPSTR)::GlobalLock(HGLOBAL(hdib));

      imgHeight = ::DIBHeight(lp);

      imgWidth = ::DIBWidth(lp);

      LPSTR lpdibdata=(LPSTR)::FindDIBBits(lp);

      memcpy(texBits,lpdibdata,imgHeight*imgWidth*3);

      ::GlobalUnlock(HGLOBAL(hdib));

      myFile.Close();

}

void CGIS1002_10View::RenderScene()

{

      glPushMatrix();

      glRotatef(xRotAngle, 1.0f, 0.0f, 0.0f);

      glRotatef(yRotAngle, 0.0f, 1.0f, 0.0f);

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      glTexImage2D(GL_TEXTURE_2D, 0, 3, imgHeight, imgWidth, 0,GL_BGR_EXT,GL_UNSIGNED_BYTE, &(GLubyte)texBits[0][0][0]);

      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

    glEnable(GL_TEXTURE_2D);

    glBegin(GL_QUADS);

      glNormal3f( 0.0F, 0.0F, 1.0F);

      glTexCoord2f(1.0,1.0);

    glVertex3f( 0.5F, 0.5F, 0.5F);

      glTexCoord2f(0.0,1.0);

      glVertex3f(-0.5F, 0.5F, 0.5F);

      glTexCoord2f(0.0,0.0);

      glVertex3f(-0.5F,-0.5F, 0.5F);

      glTexCoord2f(1.0,0.0);

      glVertex3f( 0.5F,-0.5F, 0.5F);

      glDisable(GL_TEXTURE_2D);

    glNormal3f( 0.0F, 0.0F,-1.0F);

      glTexCoord2f(1.0,1.0);

    glVertex3f(-0.5F,-0.5F,-0.5F);

      glTexCoord2f(0.0,1.0);

      glVertex3f(-0.5F, 0.5F,-0.5F);

      glTexCoord2f(0.0,0.0);

    glVertex3f( 0.5F, 0.5F,-0.5F);

      glTexCoord2f(1.0,0.0);

      glVertex3f( 0.5F,-0.5F,-0.5F);

      glDisable(GL_TEXTURE_2D);

    glNormal3f( 0.0F, 1.0F, 0.0F);

      glTexCoord2f(1.0,1.0);

    glVertex3f( 0.5F, 0.5F, 0.5F);

      glTexCoord2f(0.0,1.0);

      glVertex3f( 0.5F, 0.5F,-0.5F);

      glTexCoord2f(0.0,0.0);

    glVertex3f(-0.5F, 0.5F,-0.5F);

      glTexCoord2f(1.0,0.0);

      glVertex3f(-0.5F, 0.5F, 0.5F);

      glDisable(GL_TEXTURE_2D);

    glNormal3f( 0.0F,-1.0F, 0.0F);

      glTexCoord2f(1.0,1.0);

    glVertex3f(-0.5F,-0.5F,-0.5F);

      glTexCoord2f(0.0,1.0);

      glVertex3f( 0.5F,-0.5F,-0.5F);

      glTexCoord2f(0.0,0.0);

    glVertex3f( 0.5F,-0.5F, 0.5F);

      glTexCoord2f(1.0,0.0);

      glVertex3f(-0.5F,-0.5F, 0.5F);

      glDisable(GL_TEXTURE_2D);

    glNormal3f( 1.0F, 0.0F, 0.0F);

      glTexCoord2f(1.0,1.0);

    glVertex3f( 0.5F, 0.5F, 0.5F);

      glTexCoord2f(0.0,1.0);

      glVertex3f( 0.5F,-0.5F, 0.5F);

      glTexCoord2f(0.0,0.0);

    glVertex3f( 0.5F,-0.5F,-0.5F);

      glTexCoord2f(1.0,0.0);

      glVertex3f( 0.5F, 0.5F,-0.5F);

      glDisable(GL_TEXTURE_2D);

    glNormal3f(-1.0F, 0.0F, 0.0F);

    glVertex3f(-0.5F,-0.5F,-0.5F);

      glVertex3f(-0.5F,-0.5F, 0.5F);

    glVertex3f(-0.5F, 0.5F, 0.5F);

      glVertex3f(-0.5F, 0.5F,-0.5F);

    glEnd();

      SwapBuffers(m_pDC->GetSafeHdc());

      glPopMatrix();

}

本次实验主要是基于OpenGL的图形学编程实验,上述代码为读纹理函数的代码以及绘场景函数RenderScene()的代码,将代码及图像文件做了稍微的改动,即将图像文件"tail.bmp"改为"b.bmp",则运行结果出现了如下图所示的画面。

三、实验总结:

通过本次的实验,我掌握了Windows编程环境中的OpenGL程序框架设计和一般的OpenGL绘图环境设置和三维场景绘制步骤,并基本了解了基本的OpenGL API应用函数的使用和参数设置,基本完成实验要求。

实验项目三:简单矢量地图系统

实验日期:2012 年 6 月 20  日

一、实验目的:

1、加强矢量数据存储管理和数据结构设计的理解。

2、理解空间数据绘制的用户-视口映射原理,掌握GIS软件视图放大\缩小\漫游操作原理及地图缓存位图绘图刷新的机制。

3、进一步掌握图形交互技术。

二、你认为实验中的较好的设计或代码:

void CGIS1002_10View::InitialCoordPara()

{

      CRect rClient;

      GetClientRect(&rClient);

      double dScaleInX =  double(rClient.Width()-2)/(map.xMax-map.xMin);

      double dScaleInY = double(rClient.Height()-2)/(map.yMax-map.yMin);

      CCoordTranse::scale = dScaleInX<dScaleInY? dScaleInX:dScaleInY;

      CCoordTranse::dx = -map.xMin*CCoordTranse::scale;

      CCoordTranse::dy =  map.yMin*CCoordTranse::scale+rClient.bottom;

      if (CCoordTranse::scale==dScaleInX)

             CCoordTranse::dy += (map.yMax-map.yMin)/2*CCoordTranse::scale-(rClient.Height()-2)/2;

      else if (CCoordTranse::scale==dScaleInY)

             CCoordTranse::dx += (rClient.Width()-2)/2-(map.xMax-map.xMin)/2*CCoordTranse::scale;

}

void CGIS1002_10View::OnDraw(CDC* pDC)

{

      CGIS1002_10Doc* pDoc = GetDocument();

      ASSERT_VALID(pDoc);

      // TODO: add draw code for native data here

      COLORREF bkColor = RGB(230,230,210);

      CRect rClient;

      GetClientRect(&rClient);

      GetParentFrame()->SetWindowText("中国电子地图");

      CDC* pMemDC = new CDC;

      pMemDC->CreateCompatibleDC(pDC);

      CBitmap* pOldBmp = pMemDC->SelectObject(m_pMapBmp);

      CBrush brush(RGB(253,253,245));

      pMemDC->FillRect(rClient, &brush);

      map.DrawMap(pMemDC,bkColor);

      pDC->BitBlt(0,0,rClient.Width(), rClient.Height(), pMemDC, 0, 0, SRCCOPY);

      pMemDC->SelectObject(pOldBmp);

      delete pMemDC;

}

成员函数InitialCoordPara(),其功能是用于地图坐标变换的参数设置,它较好地把地图坐标转换为屏幕坐标;OnDraw()函数中的代码用于绘制地图;

三、实验总结:

通过本次实验,我加深了对矢量数据存储管理和数据结构设计以及对空间数据绘制的用户-视口映射原理的理解,并掌握了GIS软件视图放大\缩小\漫游操作原理及地图缓存位图绘图刷新的机制,进一步掌握了图形交互技术,基本完成实验要求。

相关推荐