分享
 
 
 

三维视图绘制与消隐技术

王朝other·作者佚名  2008-06-01
窄屏简体版  字體: |||超大  

1. 问题的提出

在一些数据库治理系统或办公自动化和统计类软件中,一般具有绘制三维视图的功能。使用时通常要求在给出的表格中输入绘图的数据及视角、比例尺等参数。这只适用于小批量的统计数据绘制统计三维视图。在地质、地貌、气象、水文、交通、林业等许多领域,需要描述的某一量通常具有空间分布特征,这种空间分布数据的数量一般十分庞大,当使用上述三维视图软件绘图时经常会碰到输数表格容纳不下的问题,而且按表格重新输入数据也轻易出错和耗费许多人力。

三维视图的绘制及相应绘图数据的组织并不是一件十分困难的事,使用少量程序代码就可以实现这一目标。本文将介绍一种以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

{

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文件即可。由此可见该程序具有使用灵活,可容绘图数据量大等优点,可用于各种空间分布数据三维视图的绘制,尤其适合于大数据量绘图。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有