自從LOD地形第一節(jié)推出以來,受到不少朋友的關(guān)注,本人真是受寵若驚,無奈自己水平有限,怕寫不好讓大家對(duì)自己失望,我只能勉為其難,努力去寫,同時(shí)歡迎高人能手給于指正,大家共同學(xué)習(xí),共同提高!
LOD地形的四叉樹算法原理就是對(duì)地形進(jìn)行四叉樹分割,同時(shí)檢查該節(jié)點(diǎn)是否位于視截體內(nèi)部,如果在視截體內(nèi)部且滿足視距,周圍點(diǎn)高程誤差等條件時(shí),則對(duì)該節(jié)點(diǎn)繼續(xù)分割,否則不予分割。其中重點(diǎn)是視截體的計(jì)算,以及地形的分割及渲染。下面介紹幾個(gè)系統(tǒng)中用到的類。
首先介紹標(biāo)志節(jié)點(diǎn)是否分割的類Bit
類定義:
//該類根據(jù)節(jié)點(diǎn)的位置,為每個(gè)節(jié)點(diǎn)在標(biāo)志段里相應(yīng)位設(shè)一個(gè)標(biāo)識(shí)。
/***********************************************************************
* Copyrights Reserved by QinGeSoftware
* Author : Qinge
* Filename : Bit.h 1.0
* Date: 2008-1-10
************************************************************************/
#pragma once
class Bit
{
public:
void SetScale(int nScale); //伸縮系數(shù)
void Set(int x, int y, BOOL bFlog=TRUE); //設(shè)置標(biāo)志位
void Reset(); //標(biāo)志清零
BOOL CreateBits(int nXBites, int nRows); //創(chuàng)建標(biāo)志數(shù)組
BOOL IsTrue(int x, int y); //查詢?cè)撐粯?biāo)志
public:
Bit();
virtual ~Bit(void);
private:
unsigned char *m_pBits; //存儲(chǔ)位標(biāo)志的指針
int m_nXBytes; //X方向的字節(jié)數(shù)
int m_nZRows; //Z方向的行數(shù)
int m_nScale; //伸縮系數(shù)
};
//類實(shí)現(xiàn)文件
/***********************************************************************
* Copyrights Reserved by QinGeSoftware
* Author : Qinge
* Filename : Bit.cpp 1.0
* Date: 2008-1-10
************************************************************************/
#include "StdAfx.h"
#include "Bit.h"
Bit::Bit(void)
{
m_pBits = NULL; //指針初始化為NULL
m_nXBytes = 0;
m_nZRows = 0;
m_nScale = 1; //不能初始化為0,因?yàn)槭浅龜?shù)
}
Bit::~Bit(void)
{
if(m_pBits != NULL)
{
delete [] m_pBits; //釋放指針
m_pBits = NULL; //置為空,否則會(huì)成為野指針
}
}
BOOL Bit::CreateBits(int nXBites, int nRows)
{
//nXBits 必須是8的倍數(shù)
m_nXBytes = nXBites/8+1; //想想為什么加1
m_nZRows = nRows;
m_pBits = new unsigned char[m_nXBytes * m_nZRows]; //分配空間
memset(m_pBits, 0, m_nZRows * m_nXBytes); //標(biāo)志段全部初始化0
return 0;
}
void Bit::SetScale(int nScale)
{
m_nScale = nScale; //提供操作私有變量的接口
}
void Bit::Set(int x, int y, BOOL bFlog )
{
x = x / m_nScale; //每隔m_nScale采樣
y = y / m_nScale;
unsigned char &c = m_pBits[y * m_nXBytes + x/8]; //獲得某字符的引用,注意賦值方式,否則
unsigned char d = 0x80; //后面改了白該。
d = d >>(x%8); //根據(jù)X值得不同,首位右移相應(yīng)位數(shù)。移位
// 使得每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一位。
if(bFlog)
{
c|=d; //把字符C與X相應(yīng)的位置為1
}
else
{
d = ~d; //和某節(jié)點(diǎn)對(duì)應(yīng)的位為0,其余位為1
c &= d; //把字符C與X相應(yīng)的位置為0
}
}
void Bit::Reset()
{
memset(m_pBits, 0, m_nXBytes * m_nZRows);
}
BOOL Bit::IsTrue(int x, int y)
{
x = x/m_nScale;
y = y/m_nScale;
unsigned char c = m_pBits[y*m_nXBytes+x/8]; //這次不是引用,想想為什么
unsigned char d = 0x80;
c = c << (x%8); //為什么不是d移位?
return c&d; //把與X對(duì)應(yīng)的位返回,其余位為0
}
//該函數(shù)得到字符包含包含8個(gè)節(jié)點(diǎn)的標(biāo)志,必須根據(jù)X的值進(jìn)行移位方能找到對(duì)應(yīng)的節(jié)點(diǎn),這次是取得標(biāo)識(shí)而不是設(shè)置標(biāo)識(shí),故不用引用。c移位而不是d移位,是為了把標(biāo)識(shí)移到首位。然后和0x80進(jìn)行位與操作得到BOOL值。d移位操作效果是一樣的,但不是左移而是右移。