于海乾 王海波
摘要:在山區(qū)地形測繪中我們需要對等高線進行計算機自動光滑與過濾處理,來提高作業(yè)效率。雖然我們?nèi)粘J褂媚戏焦净贏utoCAD二次開發(fā)的Cass軟件有擬合與過濾功能,但它不能達到我們想要的效果,因此作者想到了另一種處理算法,下面我們來闡述這種算法。
關(guān)鍵詞:等高線;光滑;過濾
一、等高線的光滑
光滑等高線有兩個要求,第一是要保持等高線的原來位置不變,第二是不能有尖角。這是兩個相互矛盾的要求,要滿足這兩個要求我們需要分兩步走:
第一步:例如圖1所示,我們還從等高線的當(dāng)前點出發(fā),設(shè)當(dāng)前點為n,第二個點n+1,第三點n+2,設(shè)n點坐標(biāo)X0,Y0;設(shè)n+1的坐標(biāo)為X1,Y1;設(shè)n+2的坐標(biāo)為X2,Y2;要把n+1點處的尖角去掉,取a邊和b邊中距離短的一邊的四分之一(Dis),用這個距離作為參數(shù)求出n+1點附近處的兩個點n+3,n+4。設(shè)n+3的坐標(biāo)為X3,Y3;設(shè)n+4的坐標(biāo)為X4,Y4.求n+3,n+4點坐標(biāo)的公式如下:
X3=X0+(X1-X0)*dis/a
Y3=Y0+(Y1-Y0)*dis/a
X4=X2+(X1-X2)*dis/b
Y4=Y2+(Y1-Y2)*dis/b
說明一下:圖2為去除尖角后的圖,上面的“1/4”是個參數(shù),作者在幾次試驗后發(fā)現(xiàn)用這個參數(shù)比較合理,既可以去掉尖角又不致超過限差的改變等高線的位置。在使用過程中我們可以多次使用此步,讓等高線變得比較光滑。
第二步:使用3次B樣擬合公式對等高線進行擬合處理,設(shè)等高線上的當(dāng)前點為n,擬合公式為:
f0=1/6*(-T^3+3*T^2-3*T+1)
f1=1/6*(3*T^3-6*T^2+4)
f2=1/6*(-3*T^3+3*T^2+3*T+1)
f3=1/6*T^3
x=f0*Px(n)+f1*Px(n+1)+f2*Px(n+2)+f3*Px(n+3)
y=f0*Py(n)+f1*Py(n+1)+f2*Py(n+2)+f3*Py(n+3)
T為小于等于1的參數(shù),計算公式為:i/m,其中”i”為從”0”到”m”的變量,”m”為要添加的節(jié)點數(shù)目。
Px為橫坐標(biāo)點數(shù)組,Py為縱坐標(biāo)點數(shù)組。
x,y為光滑后的等高線上的節(jié)點坐標(biāo)。
上面的算法已用程序?qū)崿F(xiàn),以下為主要部分源代碼:
Sub CreateFittingLine()
Dim Sset As AcadSelectionSet
Dim filterType(0)As Integer
Dim filterData(0)As Variant
filterType(0)=0
filterData(0)="*line"
On Error Resume Next
If Not IsNull(ThisDrawing.SelectionSets.Item("Example"))Then
Set Sset=ThisDrawing.SelectionSets.Item("Example")
Sset.Delete
End If
Set Sset=ThisDrawing.SelectionSets.Add("Example")
Sset.SelectOnScreen filterType,filterData
Dim Obj As AcadEntity
Dim k As Integer
Dim a0,a1,a2,a3 As Integer '幾個在閉合曲線中使用的參數(shù)
For k=0 To Sset.count-1
Set Obj=Sset.Item(k)
'3次B樣擬合算法
Dim Px()As Double
Dim Py()As Double
Dim i,j,m,n As Integer
Dim T As Double
Dim f0,f1,f2,f3 As Double
Dim x,y As Double
Dim gc As Long '等高線的高程
m=GetVertexCount(Obj)-1
Dim Zb1()As Double
Dim Zb2()As Double
ReDim Zb1(2*m+1)As Double
For i=0 To m
Zb1(2*i)=Obj.Coordinate(i)(0)
Zb1(2*i+1)=Obj.Coordinate(i)(1)
Next i
Call changeOneRoleToFour(Zb1,Zb2)'去除距離太近的點‘可以通過改變此函數(shù)中的距離參數(shù)來提高線的圓滑,可是有可能照成點線不一。把尖角變成4個角
m=(UBound(Zb2)+1)/2-1 '現(xiàn)在有m+1個點
ReDim Px(m)As Double
ReDim Py(m)As Double
For i=0 To m
Px(i)=Zb2(2*i)
Py(i)=Zb2(2*i+1)
Next i
Dim Zb()As Double
'MsgBox Px(m)
n=-1
If Obj.Closed=False Then '不閉合的曲線與閉合的曲線處理起來是不一樣的,先處理不閉合的曲線。
For j=0 To m-2
If j=0 Then '把起點帶上
a0=j
a1=j
a2=j
a3=j
ElseIf j > m-3 Then '把終點帶上
a0=m
a1=m
a2=m
a3=m
Else
a0=j
a1=j+1
a2=j+2
a3=j+3
End If
For i=0 To 3 '"3是個參數(shù),參數(shù)越大等高線上節(jié)點越多"
T=i/3
f0=1/6*(-T^3+3*T^2-3*T+1)
f1=1/6*(3*T^3-6*T^2+4)
f2=1/6*(-3*T^3+3*T^2+3*T+1)
f3=1/6*T^3
x=f0*Px(a0)+f1*Px(a1)+f2*Px(a2)+f3*Px(a3)
y=f0*Py(a0)+f1*Py(a1)+f2*Py(a2)+f3*Py(a3)
n=n+1
ReDim Preserve Zb(2*n+1)As Double
Zb(2*n)=x
Zb(2*n+1)=y
Next i
Next j
ElseIf Obj.Closed=True Then '處理閉合曲線
For i=0 To 3 '"3是個參數(shù),參數(shù)越大等高線上節(jié)點越多"
T=i/3
f0=1/6*(-T^3+3*T^2-3*T+1)
f1=1/6*(3*T^3-6*T^2+4)
f2=1/6*(-3*T^3+3*T^2+3*T+1)
f3=1/6*T^3
x=f0*Px(a0)+f1*Px(a1)+f2*Px(a2)+f3*Px(a3)
y=f0*Py(a0)+f1*Py(a1)+f2*Py(a2)+f3*Py(a3)
n=n+1
ReDim Preserve Zb(2*n+1)As Double
Zb(2*n)=x
Zb(2*n+1)=y
Next
Next j
End If '分閉合曲線與不閉合曲線
'gc=obj.Elevation
Dim Pts()As Double
Call ThreeFiltrates(Zb,Pts)'對生成的坐標(biāo)過濾
Call AddNewdgx(Pts,Obj)
Obj.Delete
Next k
End Sub
二、等線的過濾:
CASS中也有等高線過濾的功能,即“復(fù)合線濾波”,但此功能并不能很好的完成既過濾掉等高線上多余的節(jié)點又保持等線的原來位置,例如當(dāng)濾波值設(shè)小了過濾不完等高線上多余的節(jié)點;大了又改變了等高線的位置,如圖1,圖2所示。
圖3為過濾前的等高線。
于是作者想到了另一個算法即能過濾掉等高線上節(jié)點又能保持等高線位置。
我們從等高線的起點開始,設(shè)當(dāng)前點為”n”,第二個為”n+1”,第三個為”n+2”,我們把三個點組成一個三角形,算出”n+1”點到底邊的垂直距離”h”。我們可以設(shè)置一個參數(shù),用于決定是否保留”n+1”點,當(dāng)h大于這參數(shù)時去掉,小于時保留。計算”h”的公式:
h=2*area/c
area=s(s-a)(s-b)(s-c)
其中”area”為上面三角形的面積,”s”為三角形的周長,”a”為點”n”到”n+1”的邊,”b”為”n+1”到”n+2”的邊,”c”為點”n+2”到”n”的邊。
此算法的好處在于可以保證等高線的位置不變又可以充分的過濾掉多余的節(jié)點,例如我們把參數(shù)設(shè)為“0.2”,等高線部分位置挪動0.2m,對等高線來說沒有影響,但是卻可以過濾掉絕大過多數(shù)多余的節(jié)點。
總結(jié):
等高線的光滑中,第一步加點是為了保證使用擬合公式后等高線的位置不至移動太大,可以保持在正確的位置上同時初步光滑;第二步使用擬合公式擬合是讓等高線完全光滑。大量的事實也證明這兩步結(jié)合起來使用,等高線可以變得即光滑又能保證在原來的位置。使用擬合公式而不使用Cass的擬合功能是因為Cass的擬合功能改變了多段線的屬性,我們在進一步整理等高線時會變得很不方便,使用擬合公式處理出來的等高線不但達到了比擬合功能更好的效果而且不改變等高線的性質(zhì),不影響進一步的處理工作。再使用過濾程序可以過濾后,等高線上多余節(jié)點被去掉而等高線位置不變。這樣就達到我們所要的效果,在大面積山區(qū)測繪中對能明顯提高內(nèi)業(yè)的作業(yè)效率。
參考文獻:
[1]《AutoCAD VBA二次開發(fā)教程》。