C++实现三维视图绘制与消隐技术

2016-02-19 18:34 198 1 收藏

今天图老师小编要跟大家分享C++实现三维视图绘制与消隐技术,精心挑选的过程简单易学,喜欢的朋友一起来学习吧!

【 tulaoshi.com - 编程语言 】

1. 问题的提出
  
  在一些数据库治理系统或办公自动化和统计类软件中,一般具有绘制三维视图的功能。使用时通常要求在给出的表格中输入绘图的数据及视角、比例尺等参数。这只适用于小批量的统计数据绘制统计三维视图。 !-- frame contents -- !-- /frame contents -- 在地质、地貌、气象、水文、交通、林业等许多领域,需要描述的某一量通常具有空间分布特征,这种空间分布数据的数量一般十分庞大,当使用上述三维视图软件绘图时经常会碰到输数表格容纳不下的问题,而且按表格重新输入数据也轻易出错和耗费许多人力。
  
  三维视图的绘制及相应绘图数据的组织并不是一件十分困难的事,使用少量程序代码就可以实现这一目标。本文将介绍一种以C++语言实现大批量数据绘制三维视图的简易方法。该法的要害技术在于:
  
  (1)以FoXPro数据库治理系统整理绘图数据并制成可为C++语言包括和调用的.h文件;
  
  (2)在绘制三维视图中,以“多边形法”进行需遮蔽线段的消隐。
  
  2. 绘图数据的预备
  
  绘图的原始数据来自FoxPro(或FoxBase)数据库治理系统。可以将某幅图的数据置于一个一维数组中,并包括在一个.h文件中。这样只要在C++的绘三维视图程序首包括该头文件,就可以在程序的任何位置调用这些数据。例如有一个数据串:3,8,10,11,27,6,……,设存放数组为A,数据文件名为data.h,在data.h中,该数据串的存放形式为:
  
  A={ 3,8,10,11, 27, 6, : :};
  
  这些数据可由FoxPro的.dbf文件拷贝得到。当然,在拷贝前还需经过简单的加工。设在.dbf文件中,待绘图数据所在的字段为DT1,此时可增设一个字段DH(逗号),并将该字段的内容全以“,”替换,然后以如下命令拷贝到data.h文件中: copy to data.h field DT1,DH dele with blank 随后打开data.h文件,在数据首加上“A={”,在数据尾加上“ };”即可。
  
  3. 绘三维视图编程基本思想
  
  绘三维视图的要害技术在“消隐”,即消去在三维观察时应该被挡住看不见的线。在有关“计算机图形学”的书籍中所介绍的消隐法多为“计算法”,即由当前数据点行计算在已绘出的线条中哪些应该隐去,再清除这些线条。笔者自己设计了一种简便新奇的消隐法(这里姑且称之为“多边形法”),不仅程序代码简单,而且这种消隐法的原理也十分简洁明了。现将其基本思想及运算步骤介绍如下:
  
  3.1 首排数据绘X方向网线。以line函数将首排数据点连线;
  
  3.2 绘Y方向网线。将第2排与第1排在Y方向相对应的数据点连线;
  
  3.3 以“多边形法”做消隐。据第2排点的数据以背景色涂刷一个多边形,这样,可能被第2排数据点连线所遮蔽的线条(即应消隐的线)即被擦除;
  
  3.4 第2排数据绘X方向网线。以line函数将第2排数据点连线;
  
  3.5 重复步骤3.2~3.4,直至绘完全图。  4. 绘三维视图源程序(for Windows)
  
    draw3d.cpp
  
  #include
  
  #include "data.h"
  
  int PASCAL WinMain (HANDLE, HANDLE, LPSTR, int);
  
  long FAR PASCAL WindowProc (HWND, Word, WORD, LONG);
  
  int mv[15625]; // mv[ ] 为绘图数据数组,存于data.h中
  
  HANDLE hInst;
  
  int PASCAL WinMain (HANDLE hInstance, HANDLE
  hPrevInstance,
  
  LPSTR lpszCmdLine, int nCmdShow)
  
  {
  
  …… //此处略去了创建窗口的代码块
  
  }
  
  long FAR PASCAL WindowProc (HWND hWnd, WORD message,
  
  WORD wParam, LONG lParam)
  
  {
  
  HDC hDC;
  
  PAINTSTRUCT ps;
  
  HBRUSH hOldBrush;
  
  int i=0,j=0;
  
  int yy[MAXPTS]; //MAXPTS为绘图行或列数,在data.h中定
  义
  
  static POINT PointTable[MAXPTS+2];
  
  switch (message)
  
  { // 定义画笔或画刷
  
  static LOGPEN lpBlack={PS_SOLID,1,1,RGB(0,0,0)};
  
  static LOGPEN lpGreen={PS_SOLID,1,1,RGB(0,255,0)};
  
  static LOGPEN lpWhite={PS_SOLID,1,1,RGB(255,255,255)};
  
  HBRUSH hBlackBrush;
  
  HBRUSH hWhiteBrush;
  
  HPEN hGreenPen;
  
  HPEN hWhitePen;
  
  HDC hDC;
  
  PAINTSTRUCT PtStr;
  
  LoadString (hInst, IDS_CAPTION, szCaption, 35);
  
  return 0;
  
  case WM_PAINT:
  
  hDC = BeginPaint (hWnd, &PtStr);
  
  SetMapMode(hDC,MM_TEXT);
  
  hBlackPen=CreatePenIndirect(&lpBlack);
  
  hGreenPen=CreatePenIndirect(&lpGreen);
  
  hWhitePen=CreatePenIndirect(&lpWhite);
  
  hBlackBrush=GetStockObject(BLACK_BRUSH);
  
  hWhiteBrush=GetStockObject(WHITE_BRUSH);
  
  hOldBrush = SelectObject (hDC,GetStockObject
  (NULL_BRUSH));
  
  {
  
  yy[j]=MOVE+j*SCALE1; //MOVE为绘图起始点Y坐标,在
  data.h中定义
  
  for(i=0;i
  
  {
  
  PointTable[i].x=i*SCALE2+j*SCALE4; // 形成多边形顶点
  数组
  
  PointTable[i].y=yy[j]-(PointTable
  [i].x-PointTable[0].x)*ANGLE-(mv[j*MAXPTS+i]
  *SCALE3); //SCALE2和SCALE4分别为X和Y方向的缩放系数
  
  if(j0) //SCALE3为绘图数据(Z方向)的缩放系数
  
  { //ANGLE为视角,均在data.h中定义
  
  SelectObject(hDC,hGreenPen);
  
  MoveTo(hDC,mx[i],my[i]);
  
  LineTo(hDC,PointTable[i].x,PointTable[i].y); // 绘
  y 方 向 网 线
  
  }
  
  }
  
  PointTable[MAXPTS].x=PointTable[MAXPTS-1].x;
  
  PointTable[MAXPTS].y=PointTable[MAXPTS-1].y+20;
  
  PointTable[MAXPTS+1].x=PointTable[0].x;
  
  PointTable[MAXPTS+1].y=PointTable[0].y+20;
  
  if(j==(MAXPTS-1))
  
  {
  
  SelectObject(hDC,hWhitePen);
  
  SelectObject(hDC,hWhiteBrush);
  
  Polygon(hDC,PointTable,MAXPTS); // 消 隐
  
  }
  
  else
  
  {
  
  SelectObject(hDC,hBlackPen);
  
  SelectObject(hDC,hBlackBrush);
  
  Polygon(hDC,PointTable,MAXPTS); // 消 隐
  
  }
  
  for(i=0;i
  
  {
  
  mx[i]=PointTable[i].x; //将前排点数据存于mx[i]
  my[i],
  
  my[i]=PointTable[i].y; // 留待绘y方向网线
  
  }
  
  for(i=0;i(MAXPTS-1);i++)
  
  {
  
  SelectObject(hDC,hGreenPen);
  
  MoveTo(hDC,PointTable[i].x,PointTable[i].y);
  
  LineTo(hDC,PointTable[i+1].x,PointTable[i+1].y);//绘 x方向网线
  
  }
  
  }
  
  SelectObject (hDC, hOldBrush);
  
  EndPaint (hWnd, &PtStr);
  
  return 0;
  
  case WM_DESTROY:
  
  ostQuitMessage (0);
  
  return 0;
  
  default:
  
  break;
  
  }
  return DefWindowProc (hWnd, message, wParam, lParam);
   }
  5. 结论
  
  绘图数据及缩放、视角等参数皆存于data.h文件中,或在该文件中说明,所以当绘图参数等内容变化时,只要修改或重新制作data.h文件即可。
   由此可见该程序具有使用灵活,可容绘图数据量大等优点,可用于各种空间分布数据三维视图的绘制,尤其适合于大数据量绘图。

来源:http://www.tulaoshi.com/n/20160219/1618184.html

延伸阅读
标签: autocad教程
关键字:AutoCAD 2009 AutoCAD对象 中望CAD AutoCAD三维造型 AutoCAD造型 AutoCAD拉伸命令内容摘要:AutoCAD可以利用3种方式来创建三维图形,即线架模型方式、曲面模型方式和实体模型方式。线架模型方式为一种轮廓模型,它由三维的直线和曲线组成,没有面和体的特征。曲面模型用面描述三维对象,它不仅定义了三维对象的边界,而且还定义了...
如何在CAD中将三维实体转换为三视图   三维实体画好以后,可以观赏,也可以截成图片,固然漂亮、直 观,但很多信息传递不到。因此,只有把三维实体转成三视图,才是 最实用的,可以反映三维实体的各个部位的详细信息。 而怎样才能将所画好的三维实体用三视图的形式表达出来,是很 多绘图者比较头疼的事情。在平面里参照三维实体一步...
CAD教程:平面摄影命令将三维模型转为三视图 在AutoCAD2007版及以后的各个版本中,还可以用平面摄影(flatshot)命令来进行三维实体到三视图转换,这个转换过程是在模型里转换,这就给很多的后续操作带来了方便,如绘制剖视图、截面图、转向图等等。 经过本人(shaonx)一段时间的研究试验,总结了一套转换的方法,自我感觉基本上还是成...
标签: autocad教程
本例为AutoCAD实例教程,今天我们将学习通过运用AutoCAD的“设置视图(solview)”、“设置图形(soldraw)”命令将三维实体图转为三视图,希望能给朋友们带来帮助~~ 相关教程: “平面摄影(flatshot)”命令将三维模型转为三视图: 三维实体画好以后,可以观赏,也可以截成图片,固然漂亮、直观,但很多信息传递不到。因此,只有把三维...
先看看效果图。 1.使用矩形工具(M),开始绘制一个正方形。 2.执行效果菜单3D旋转,旋转正方形。你不需要按下图输入数值,但是你一定要记住你所输入的数值,因为在我们之后添加文本时,你还要用到它(注:其实不记住也没关系的,只要旋转完成后,新建个图形样式就可以了,之后要再用到这个效果时只要再应用即可)。确定后,执行对象菜单扩...

经验教程

481

收藏

22
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部