此种模型绘制类似米字形的网格。由于整个过程递归调用绘图函数,所以可以根据误差判断绘制DEM的精细程度,从而绘制出不同精细程度的DEM,为解决漫游中数据量较大而引起的画面不流畅现象提供了模型基础。 本文并没有对LOD作研究,只是给出了四叉树的建立和遍历绘图的方法。
#include
"
Pt3d.h
"
//
空间点类(主要记录空间点的x,y,z)
#define
EDGE_POINT 0
#define
NODE_POINT 1
#define
UNKNOWN 2
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
CDEM
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
public:
CString strFileName; //文件名
CString strPathName; //文件路径名
double **dDEMGrid; //原始DEM格网点高程数据
int iCols; //研究区格网列数
int iRows; //研究区格网行数
double dXllcorner; //格网左下角X坐标(起始坐标)
double dYllcorner; //格网左下角Y坐标(起始坐标)
double dCellsize; //格网大小
double dNodata; //无数据区域的标识数字
double dMinZ,dMaxZ; //最大、最小高程值
double dCenterX,dCenterY; //DEM中心的坐标
float fScale; //范围比例
float fZRatio; //DEM高程夸张系数
bool IsShow; //是否显示
CDEM();
virtual ~CDEM();
void GetDEMScope(); //获得DEM最大、最小高程值
void Draw(); //绘制DEM
bool GetPt(int i,int j,CPt3d &pt); //获得DEM中的i行j列点
//四叉树算法实现
int iLodRows,iLodCols; //经过LOD扩展后的行数和列数
int** quadtree; //四叉树边点记录
void init_quadtree(int i, int j); //初始化四叉树
void setup_quadtree(int i, int j, int width); //建立四叉树
void Draw(int i, int j, int width); //绘制四叉树
void triangle(CPt3d &pt1, CPt3d &pt2, CPt3d &pt3); //绘制三角形
}
;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
CDEM::init_quadtree(
int
iRow,
int
iCol)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i,j;
quadtree = new int *[iRow];
for(i=0; i<iRow; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
quadtree[i] = new int[iCol];
for(j=0; j<iCol; j++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
quadtree[i][j] = UNKNOWN;
}
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
CDEM::setup_quadtree(
int
i,
int
j,
int
width)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int width2;
width2 = width / 2;
if(width > 1)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
quadtree[i][j] = NODE_POINT;
setup_quadtree(i-width2,j-width2,width2);
setup_quadtree(i-width2,j+width2,width2);
setup_quadtree(i+width2,j-width2,width2);
setup_quadtree(i+width2,j+width2,width2);
}
else
quadtree[i][j] = EDGE_POINT;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
CDEM::Draw(
int
i,
int
j,
int
width)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int width2;
width2 = width / 2;
if((width > 1) && (quadtree[i][j] == NODE_POINT))
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
Draw(i-width2,j-width2,width2);
Draw(i-width2,j+width2,width2);
Draw(i+width2,j-width2,width2);
Draw(i+width2,j+width2,width2);
}
else if(quadtree[i][j] == EDGE_POINT)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//绘制8个三角行
CPt3d pt[9];
GetPt(i, j, pt[0]);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
GetPt(i-width, j-width, pt[1]);
GetPt(i, j-width, pt[2]);
GetPt(i+width, j-width, pt[3]);
GetPt(i+width, j, pt[4]);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
GetPt(i+width, j+width, pt[5]);
GetPt(i, j+width, pt[6]);
GetPt(i-width, j+width, pt[7]);
GetPt(i-width, j, pt[8]);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
int m;
for(m=1; m<8; m++)
triangle(pt[0], pt[m], pt[m+1]);
triangle(pt[0], pt[8], pt[1]);
}
else
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
return;
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
void
CDEM::triangle(CPt3d
&
pt1, CPt3d
&
pt2, CPt3d
&
pt3)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
if (pt1.z != -9999.0f * fZRatio && pt2.z != -9999.0f*fZRatio &&
pt3.z != -9999.0f * fZRatio)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
glBegin(GL_LINE_LOOP);
glBegin(GL_TRIANGLES);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex3f(pt1.x, pt1.y, pt1.z);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex3f(pt2.x, pt2.y, pt2.z);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
glVertex3f(pt3.x, pt3.y, pt3.z);
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
glEnd();
glEnd();
}
}