孫艷崇 孫國平
(1.遼寧省交通高等專科學(xué)校,遼寧沈陽 110122;2.沈陽市勘察測繪研究院,遼寧沈陽 110004)
在用VC語言開發(fā)繪圖程序中,主要利用的一個(gè)類是設(shè)備上下文對象類(CDC類),CDC類定義了一系列圖形對象及其相關(guān)的繪圖函數(shù),其中包括處理顯示器或打印機(jī)等設(shè)備上下文的成員函數(shù),以及處理與窗口客戶區(qū)對應(yīng)的顯示上下文的成員函數(shù)等。
在VC中,CDC類有成員函數(shù)Arc(),可以實(shí)現(xiàn)圓弧的繪制;使用此函數(shù)時(shí),需要已知圓弧的外切矩形的四個(gè)角點(diǎn)的坐標(biāo),以及圓弧起點(diǎn)和端點(diǎn)的坐標(biāo)。而在EVC中,其CDC類中沒有繪制圓弧的函數(shù),所以在用EVC開發(fā)測圖系統(tǒng)時(shí),其中圓弧的繪制函數(shù)需要自行編制;圓弧繪制函數(shù)的算法有很多,本文介紹了一種新的三點(diǎn)繪制圓弧的算法,其思路是采用坐標(biāo)正反算法,按一定圓心角計(jì)算圓弧點(diǎn)的坐標(biāo),然后利用繪制直線的函數(shù)(MoveTo()和LineTo()),采用直線逼近的方法實(shí)現(xiàn)。
1)坐標(biāo)方位角的定義。
在測繪學(xué)科中,為了計(jì)算坐標(biāo)的方便,除了需要知道距離,還需要知道方向,這一方向是通過坐標(biāo)方位角來描述的,坐標(biāo)方位角的定義是從某點(diǎn)的坐標(biāo)縱軸方向線起,依順時(shí)針方向到目標(biāo)方向線之間的水平夾角。
2)坐標(biāo)正算。
坐標(biāo)正算,就是根據(jù)直線的邊長、坐標(biāo)方位角和一個(gè)端點(diǎn)的坐標(biāo),計(jì)算直線另一個(gè)端點(diǎn)的坐標(biāo)的工作。
3)坐標(biāo)反算。
根據(jù)直線的起點(diǎn)和終點(diǎn)的坐標(biāo),計(jì)算直線的水平距離和坐標(biāo)方位角的過程叫坐標(biāo)反算。
在用EVC開發(fā)測圖系統(tǒng)中,各圖元的繪制都是以類的形式實(shí)現(xiàn)的,且由于所繪制的圖形要加以保存,所以相關(guān)的圖元類要直接或間接的從Cobject類派生,這樣就可以實(shí)現(xiàn)類的串行化,從而實(shí)現(xiàn)圖形數(shù)據(jù)的保存。下面介紹三點(diǎn)繪制圓弧的類中,同圓弧繪制相關(guān)的數(shù)據(jù)成員及成員函數(shù)的定義。
double radius;
//定義圓弧的半徑
void centerandradius(double x1,x2,x3,y1,y2,y3);
//通過弧上的三點(diǎn),計(jì)算圓弧的圓心坐標(biāo)和半徑,并對center_x,center_y及 radius賦值
double azimuth(double f_x,double f_y,double e_x,double e_y);
//計(jì)算一條直線的坐標(biāo)方位角,以弧度為單位
void arc(CPoint point[3],CDC*pdc);
//通過給定的三點(diǎn)及窗口的句柄,在特定的窗口,按順時(shí)針繪制圓弧
};
實(shí)現(xiàn)三點(diǎn)圓弧的繪制,需要首先計(jì)算出圓弧的圓心和半徑,其計(jì)算方法是:通過給定的三點(diǎn)組成一個(gè)三角形,然后構(gòu)造出任意兩條邊的垂直平分線的直線方程,最后對這兩條直線方程求解,即可計(jì)算出圓弧的圓心坐標(biāo),從而通過圓心坐標(biāo)和給定三點(diǎn)中的任意一點(diǎn)計(jì)算圓弧的半徑。其圓弧的圓心坐標(biāo)和半徑的計(jì)算函數(shù)如下:
測量學(xué)中,方位角的定義是:沿坐標(biāo)北方向順時(shí)針旋轉(zhuǎn)到該直線的角度,在計(jì)算圓弧上點(diǎn)的坐標(biāo)時(shí),首先選定圓弧的起始點(diǎn)和終止點(diǎn),然后分別計(jì)算出起點(diǎn)到圓心的坐標(biāo)方位角和終點(diǎn)到圓心的坐標(biāo)方位角。
其函數(shù)的具體實(shí)現(xiàn)如下:
//計(jì)算起點(diǎn)或端點(diǎn)到圓心的橫坐標(biāo)增量double D_x=e_x-f_x;
//計(jì)算起點(diǎn)或端點(diǎn)到圓心的縱坐標(biāo)增量
if(D_x==0&&D_y>0)
return pi/2;
//如果縱坐標(biāo)增量等于0,且橫坐標(biāo)增量大于0,坐標(biāo)方位角等于 π/2(90°)
else if(D_x==0&&D_y<0)
return pi/2+pi;
//如果縱坐標(biāo)增量等于0,且橫坐標(biāo)增量小于0,坐標(biāo)方位角等于 π/2+π(270°)
else
{double azimth=atan(D_y/D_x);if(D_x<0)
return azimth+pi;
//如果縱坐標(biāo)增量小于0,坐標(biāo)方位角等于計(jì)算的反正切值加上π的和
else
return azimth;
//如果縱坐標(biāo)增量大于0,坐標(biāo)方位角等于計(jì)算出的反正切值,此時(shí)計(jì)算的方位角可能出現(xiàn)負(fù)值,但對后面圓弧點(diǎn)的坐標(biāo)計(jì)算公式?jīng)]有影響,所以可以直接返回計(jì)算的反正切值
}}
在實(shí)現(xiàn)三點(diǎn)圓弧繪制的函數(shù)中,需要調(diào)用函數(shù)centerandradius(),獲取圓心坐標(biāo)和半徑,然后調(diào)用方位角計(jì)算函數(shù)azimuth()計(jì)算起終點(diǎn)到圓心的坐標(biāo)方位角,最后按一定圓心角間隔計(jì)算圓弧點(diǎn)的坐標(biāo),其函數(shù)的具體實(shí)現(xiàn)如下:
//通過圓弧上的三點(diǎn)獲取圓弧的圓心坐標(biāo)及半徑
const double PI=3.1415926;
double azimuth1=azimuth(center_x,center_y,point[0].x,point[0].y);
//計(jì)算起點(diǎn)到圓心的坐標(biāo)方位角
double azimuth2=azimuth(center_x,center_y,point[2].x,point[2].y);
//計(jì)算終點(diǎn)到圓心的坐標(biāo)方位角
doublemaxnum=azimuth2-azimuth1;
//計(jì)算起終點(diǎn)到圓心的坐標(biāo)方位角的差值
if(maxnum<0)
{maxnum=maxnum+(2*PI);
//計(jì)算的差值如是負(fù)數(shù),需要加上2π
在嵌入式開發(fā)測圖系統(tǒng)時(shí)發(fā)現(xiàn):用VC開發(fā)桌面繪圖系統(tǒng)比較容易實(shí)現(xiàn)的功能,例如:圖形的無極縮放、樣條曲線函數(shù)的繪制及圖元屬性的定義等等,在EVC開發(fā)嵌入式繪圖系統(tǒng)中,要想實(shí)現(xiàn)這些功能,都是較麻煩的,因?yàn)樵贓VC中沒有實(shí)現(xiàn)此功能的基本函數(shù),所有功能都需要用戶從底層自己開發(fā)。將計(jì)算機(jī)技術(shù)的進(jìn)步與測繪工程實(shí)踐相結(jié)合,可以極大提高生產(chǎn)效率、降低生產(chǎn)成本,直接在WinCE GPS手簿上開發(fā)測圖系統(tǒng)相比在PDA上開發(fā)更加方便,因?yàn)槭∪チ巳緝x和PDA數(shù)據(jù)通訊的開發(fā)環(huán)節(jié),這樣降低了開發(fā)周期,而且用GPS進(jìn)行數(shù)據(jù)采集相比全站儀更加方便快捷,因?yàn)橹灰獙⒒鶞?zhǔn)站架設(shè)好之后,不用轉(zhuǎn)站就可以用流動(dòng)站采集數(shù)據(jù)?;谝陨蟽?yōu)點(diǎn),直接在WinCE GPS手簿上開發(fā)成圖系統(tǒng)能提高工作效率,這也將成為數(shù)字化測圖的一個(gè)新的發(fā)展方向。
[1]孫 群.?dāng)?shù)字測圖系統(tǒng)研制報(bào)告[R].鄭州:解放軍信息工程大學(xué)測繪學(xué)院,2005.
[2]顧孝烈,鮑 峰.測量學(xué)[M].上海:同濟(jì)大學(xué)出版社,2006.
[3]傅 曦,齊 宇.嵌入式系統(tǒng)Windows CE開發(fā)技巧與實(shí)例[M].北京:化學(xué)工業(yè)出版社,2004.