三维地形绘制--四叉树递归算法

此种模型绘制类似米字形的网格。由于整个过程递归调用绘图函数,所以可以根据误差判断绘制DEM的精细程度,从而绘制出不同精细程度的DEM,为解决漫游中数据量较大而引起的画面不流畅现象提供了模型基础。 本文并没有对LOD作研究,只是给出了四叉树的建立和遍历绘图的方法。

 

#include  " Pt3d.h "    // 空间点类(主要记录空间点的x,y,z)

#define  EDGE_POINT 0
#define  NODE_POINT 1
#define  UNKNOWN    2

class  CDEM  
{
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); //绘制三角形
}
;

void  CDEM::init_quadtree( int  iRow,  int  iCol)
{
 
int i,j;
 quadtree 
= new int *[iRow];
 
for(i=0; i<iRow; i++)
 
{
  quadtree[i] 
= new int[iCol];
  
for(j=0; j<iCol; j++)
  
{
   quadtree[i][j] 
= UNKNOWN;
  }

 }

}


void  CDEM::setup_quadtree( int  i,  int  j,  int  width)
{
 
int width2;
 width2 
= width / 2;
 
if(width > 1)
 
{
  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;
}


void  CDEM::Draw( int  i,  int  j,  int  width)
{
 
int width2;
 width2 
= width / 2;
 
if((width > 1&& (quadtree[i][j] == NODE_POINT))
 
{
  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)
 
{
  
//绘制8个三角行
  CPt3d pt[9];
  GetPt(i, j, pt[
0]);

  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]);

  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]);

  
int m;
  
for(m=1; m<8; m++)
   triangle(pt[
0], pt[m], pt[m+1]);
  triangle(pt[
0], pt[8], pt[1]);
 
 }

 
else 
 
{
  
return;
 }

}


void  CDEM::triangle(CPt3d  & pt1, CPt3d  & pt2, CPt3d  & pt3)

 
if (pt1.z != -9999.0f * fZRatio && pt2.z != -9999.0f*fZRatio &&
  pt3.z 
!= -9999.0f * fZRatio)
 

  glBegin(GL_LINE_LOOP);
   glBegin(GL_TRIANGLES); 

    glColor4f(
1.0f0.0f0.0f1.0f);
    glVertex3f(pt1.x, pt1.y, pt1.z);

    glColor4f(
1.0f0.0f0.0f1.0f);
    glVertex3f(pt2.x, pt2.y, pt2.z);

    glColor4f(
1.0f0.0f0.0f1.0f);
    glVertex3f(pt3.x, pt3.y, pt3.z);

   glEnd();
  glEnd();
 }

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值