www.pudn.com > contour234.zip > Module1.bas, change:2004-11-24,size:15559b
Attribute VB_Name = "Module1"
Type dot
X As Double
Y As Double
Z As Integer
End Type
Type edge
dot1 As dot
dot2 As dot
sign As Boolean
End Type
Type CircleRROO
RR As Double
OO As dot
End Type
Type Sdot
DD As dot
JJ As Boolean
End Type
Type triangle
A As dot
B As dot
C As dot
End Type
Public STdot(1000) As dot
Public STedge(3000) As edge
Public STtriangle(2000) As triangle
Public i As Integer
Public MaxNdot As Integer
Public MaxNedge As Integer
Public NedgeNOuse As Integer
Public Ntriangle As Integer
Public Sub GetFirstEdge() '寻找第一条边,也即两条基线
Dim L1, L2 As Double
Dim Center As dot
Dim Mark1, Mark2 As Integer
Dim Dnear, Dnear2, Dcurrent, Dcurrent2 As Double
Dim biaMaxndot As edge
Dim Xmin, Xmax, Ymin, Ymax As Integer
Dim kj, kj2, kj3 As Integer
Dim Esp4 As Double
Esp4 = 0.0000001
'//////////////////////////////////找中间点,找近点的中心
Xmin = STdot(0).X
Xmax = STdot(0).X
Ymin = STdot(0).Y
Ymin = STdot(0).Y
For kj = 0 To MaxNdot
If STdot(kj).X Xmin Then
Xmin = STdot(kj).X
End If
If STdot(kj).X > Xmax Then
Xmax = STdot(kj).X
End If
If STdot(kj).Y Ymin Then
Ymin = STdot(kj).Y
End If
If STdot(kj).Y > Ymax Then
Ymax = STdot(kj).Y
End If
Next kj
Center.X = (Xmin + Xmax) / 2
Center.Y = (Ymin + Ymax) / 2
Form1.Pic1.DrawWidth = 5
Form1.Pic1.PSet (Center.X, Center.Y)
Form1.Pic1.DrawWidth = 1
' Form1.Pic1.Circle (Center.h, Center.v), 200
Dnear = (Center.X - STdot(0).X) ^ 2 + (Center.Y - STdot(0).Y) ^ 2 '假设第一个点到中心的距离最近
Mark1 = 0
For kj2 = 1 To MaxNdot
' L1 = (Abs(stdot(kj2).h - Center.h) + Abs(stdot(kj2).v - Center.v))
' If L1 > Esp4 Then
Dcurrent = (Center.X - STdot(kj2).X) ^ 2 + (Center.Y - STdot(kj2).Y) ^ 2
If Dcurrent Dnear Then
Mark1 = kj2
Dnear = Dcurrent
End If
' End If
Next kj2 'first yellow
'MsgBox (Mark1)
Form1.Pic1.Circle (STdot(Mark1).X, STdot(Mark1).Y), 200, RGB(255, 0, 0)
'////////////////////////////////////////////////////////////////////////////////////
'找第二个点
'////////////////////////////////////////////////////////////////////////////////////
'////////////////////////////////////////////////////////////////////////////////////
Dnear2 = (STdot(Mark1).X - STdot(0).X) ^ 2 + (STdot(Mark1).Y - STdot(0).Y) ^ 2 '如果第一个点是距离中心最近的点
Mark2 = 0
If Abs(Dnear2) Esp4 Then '设离第一点最近的点是第二个点
Dnear2 = (STdot(Mark1).X - STdot(1).X) ^ 2 + (STdot(Mark1).Y - STdot(1).Y) ^ 2
Mark2 = 1
End If
For kj3 = 0 To MaxNdot
L2 = (Abs(STdot(kj3).X - STdot(Mark1).X) + Abs(STdot(kj3).Y - STdot(Mark1).Y)) '保证取点不是MARK1同一点
If L2 > Esp4 Then
Dcurrent2 = (STdot(Mark1).X - STdot(kj3).X) ^ 2 + (STdot(Mark1).Y - STdot(kj3).Y) ^ 2
If Dcurrent2 Dnear2 Then
Mark2 = kj3
Dnear2 = Dcurrent2
End If
End If
Next kj3
'MsgBox (Mark2)
Form1.Pic1.Circle (STdot(Mark2).X, STdot(Mark2).Y), 200, RGB(0, 0, 255)
' Form1.Pic1.Line (stdot(Mark1).h, stdot(Mark1).v)-(stdot(Mark2).h, stdot(Mark2).v)
'////////////////////////////////////////////////////////////////////////////////////
Form1.Text1.Text = Mark1
Form1.Text2.Text = Mark2
STedge(0).dot1 = STdot(Mark1)
STedge(0).dot2 = STdot(Mark2)
STedge(0).sign = False
STedge(1).dot1 = STdot(Mark2)
STedge(1).dot2 = STdot(Mark1)
STedge(1).sign = False
End Sub
Public Function OnLeft(A1 As dot, B1 As dot, C1 As dot) As Boolean '判断有无点在线段左边
Dim km As Double
Dim bm As Double
Dim Esp1 As Double
Esp1 = 0.0000001
OnLeft = FA1lse
If A1.X <> B1.X Then '构造直线
km = (B1.Y - A1.Y) / (B1.X - A1.X)
bm = ((A1.Y - km * A1.X) + (B1.Y - km * B1.X)) / 2
If B1.X > A1.X Then
If C1.Y - (km * C1.X + bm) > Esp1 Then
OnLeft = True
End If
ElseIf B1.X A1.X Then
If (km * C1.X + bm) - C1.Y > Esp1 Then
OnLeft = True
End If
Else
End If
ElseIf A1.X = B1.X Then
If B1.Y > A1.Y Then
If A1.X - C1.X > Esp1 Then
OnLeft = True
End If
ElseIf B1.Y A1.Y Then
If C1.X - A1.X > Esp1 Then
OnLeft = True
End If
Else
End If
Else
End If
End Function
Public Function CreateCircle(A As dot, B As dot, C As dot) As CircleRROO ' 获得外接圆的半径,圆心
Dim Km1 As Double
Dim Km2 As Double
Dim Bm1 As Double
Dim Bm2 As Double
Dim Mid1 As dot
Dim Mid2 As dot
Dim YX As dot
Dim BJ As Double
' MsgBox "CreateCircle"
Mid1.X = (A.X + B.X) / 2
Mid1.Y = (A.Y + B.Y) / 2
Mid2.X = (A.X + C.X) / 2
Mid2.Y = (A.Y + C.Y) / 2
If A.Y = B.Y Then
'MsgBox "CreateCircle:A.Y = B.Y"
YX.X = Mid1.X
Km2 = -(C.X - A.X) / (C.Y - A.Y)
Bm2 = Mid2.Y - Km2 * Mid2.X
YX.Y = Km2 * YX.X + Bm2
End If
If A.Y = C.Y Then
' MsgBox "CreateCircle:A.Y = C.Y"
YX.X = Mid2.X
YX.Y = Mid2.Y
Km1 = -(B.X - A.X) / (B.Y - A.Y)
Bm1 = Mid1.Y - Km1 * Mid1.X
YX.Y = Km1 * YX.X + Bm1
End If
If A.Y <> B.Y And A.Y <> C.Y Then
'MsgBox "CreateCircle:A.Y <> B.Y AND A.Y <> C.Y "
Km1 = -(B.X - A.X) / (B.Y - A.Y)
Bm1 = Mid1.Y - Km1 * Mid1.X
Km2 = -(C.X - A.X) / (C.Y - A.Y)
Bm2 = Mid2.Y - Km2 * Mid2.X
YX.X = -(Bm2 - Bm1) / (Km2 - Km1)
YX.Y = ((Km1 * YX.X + Bm1) + (Km2 * YX.X + Bm2)) / 2
End If
BJ = Sqr((A.X - YX.X) ^ 2 + (A.Y - YX.Y) ^ 2)
CreateCircle.OO = YX
CreateCircle.RR = BJ
End Function
Public Function NullCircle(O As dot, R As Double) As Boolean '判断是否是空圆
Dim Esp2 As Double
Dim L As Double
' MsgBox "NullCircle"
Esp2 = 0.0000001
NullCircle = True
For i = 0 To MaxNdot
L = Sqr((STdot(i).X - O.X) ^ 2 + (STdot(i).Y - O.Y) ^ 2)
If R - L > Esp2 Then
NullCircle = False
Exit Function
End If
Next i
End Function
Public Function GetThirdDot(F As dot, S As dot) As Sdot '寻找合适的第三点,找到返回该点,找不到,返回false
Dim j1 As Integer
Dim YX As dot
Dim BJ As Double
Dim DSD As dot
GetThirdDot.JJ = False
' MsgBox "GetThirdDot"
For j1 = 0 To MaxNdot
If OnLeft(F, S, STdot(j1)) = True Then
YX = CreateCircle(F, S, STdot(j1)).OO
BJ = CreateCircle(F, S, STdot(j1)).RR
If NullCircle(YX, BJ) = True Then
GetThirdDot.JJ = True
GetThirdDot.DD = STdot(j1)
MsgBox (j1)
'储存边,记录三角形
Exit Function
End If
End If
Next j1
'存储边
End Function
Public Sub Deal2Dot(A2 As dot, B2 As dot) '找不到合适第三点时,处理该边
Dim j2 As Integer
Dim Lx, Ly, Rx, Ry As Double
Dim Nunber1 As Double
Dim Esp3 As Double
Esp3 = 0.0000001
For j2 = 0 To MaxNedge
Lx = STedge(j2).dot1.X: Ly = STedge(j2).dot1.Y
Rx = STedge(j2).dot2.X: Ry = STedge(j2).dot2.Y
Nunber1 = Abs(Lx - A2.X) + Abs(Ly - A2.Y) + Abs(Ry - B2.Y) + Abs(Ry - B2.Y)
If Nunber1 Esp3 Then '找到原来位置,修改原来的基线,修改可用边数
'If STedge(j2).sign = False Then
STedge(j2).sign = True
NedgeNOuse = NedgeNOuse - 1
Form1.Pic1.Line (A2.X, A2.Y)-(B2.X, B2.Y), RGB(255, 0, 0)
'Else
' MaxNedge = MaxNedge + 1
' STedge(MaxNedge).dot1 = A2
' STedge(MaxNedge).dot2 = B2
' STedge(MaxNedge).sign = True
End If
Next j2
End Sub
Public Sub Deal3Dot(A3 As dot, B3 As dot, C3 As dot) '修改可用边数,存储边,存储三角形
Dim j31, j32, j33, j34, j35, j36 As Integer
Dim WAB, WBC, WCA, WBA, WCB, WAC As Double
Dim LnowX, LnowY, RnowX, RnowY As Double
Dim Esp5 As Double
Esp5 = 0.0000001
STedge(MaxNedge + 1).dot1 = A3: STedge(MaxNedge + 1).dot2 = B3: STedge(MaxNedge + 1).sign = True
STedge(MaxNedge + 2).dot1 = B3: STedge(MaxNedge + 2).dot2 = C3: STedge(MaxNedge + 2).sign = True
STedge(MaxNedge + 3).dot1 = C3: STedge(MaxNedge + 3).dot2 = A3: STedge(MaxNedge + 3).sign = True
STedge(MaxNedge + 4).dot1 = B3: STedge(MaxNedge + 4).dot2 = A3: STedge(MaxNedge + 4).sign = False
STedge(MaxNedge + 5).dot1 = C3: STedge(MaxNedge + 5).dot2 = B3: STedge(MaxNedge + 5).sign = False
STedge(MaxNedge + 6).dot1 = A3: STedge(MaxNedge + 6).dot2 = C3: STedge(MaxNedge + 6).sign = False
NedgeNOuse = NedgeNOuse + 3
For j31 = 0 To MaxNedge
LnowX = STedge(j31).dot1.X: LnowY = STedge(j31).dot1.Y
RnowX = STedge(j31).dot2.X: RnowY = STedge(j31).dot2.Y
WAB = Abs(LnowX - A3.X) + Abs(LnowY - A3.Y) + Abs(RnowX - B3.X) + Abs(RnowY - B3.Y)
If WAB Esp5 Then '找到原来位置,修改原来的基线,修改可用边数
If STedge(j31).sign = False Then
STedge(j31).sign = True
' MsgBox "change NedgeNOuse"
NedgeNOuse = NedgeNOuse - 1
' Form1.Text5.Text = NedgeNOuse
' MsgBox "change"
End If
End If
Next j31
For j32 = 0 To MaxNedge
LnowX = STedge(j32).dot1.X: LnowY = STedge(j32).dot1.Y
RnowX = STedge(j32).dot2.X: RnowY = STedge(j32).dot2.Y
WBC = Abs(LnowX - B3.X) + Abs(LnowY - B3.Y) + Abs(RnowX - C3.X) + Abs(RnowY - C3.Y)
If WBC Esp5 Then '找到原来位置,修改原来的基线,修改可用边数
If STedge(j32).sign = False Then
STedge(j32).sign = True
NedgeNOuse = NedgeNOuse - 1
End If
End If
Next j32
For j33 = 0 To MaxNedge
LnowX = STedge(j33).dot1.X: LnowY = STedge(j33).dot1.Y
RnowX = STedge(j33).dot2.X: RnowY = STedge(j33).dot2.Y
WCA = Abs(LnowX - C3.X) + Abs(LnowY - C3.Y) + Abs(RnowX - A3.X) + Abs(RnowY - A3.Y)
If WCA Esp5 Then '找到原来位置,修改原来的基线,修改可用边数
' MsgBox "3-1"
If STedge(j33).sign = False Then
STedge(j33).sign = True
NedgeNOuse = NedgeNOuse - 1
End If
End If
Next j33
For j34 = 0 To MaxNedge
LnowX = STedge(j34).dot1.X: LnowY = STedge(j34).dot1.Y
RnowX = STedge(j34).dot2.X: RnowY = STedge(j34).dot2.Y
WBA = Abs(LnowX - B3.X) + Abs(LnowY - B3.Y) + Abs(RnowX - A3.X) + Abs(RnowY - A3.Y)
If WBA Esp5 Then '找到原来位置,修改原来的基线,修改可用边数
If STedge(j34).sign = True Then
STedge(MaxNedge + 4).sign = True
NedgeNOuse = NedgeNOuse - 1
End If
End If
Next j34
For j35 = 0 To MaxNedge
LnowX = STedge(j35).dot1.X: LnowY = STedge(j35).dot1.Y
RnowX = STedge(j35).dot2.X: RnowY = STedge(j35).dot2.Y
WCB = Abs(LnowX - C3.X) + Abs(LnowY - C3.Y) + Abs(RnowX - B3.X) + Abs(RnowY - B3.Y)
If WCB Esp5 Then '找到原来位置,修改原来的基线,修改可用边数
If STedge(j35).sign = True Then
' MsgBox " 第5条基线原来用过,现在未用了,修改 "
STedge(MaxNedge + 5).sign = True
NedgeNOuse = NedgeNOuse - 1
' Form1.Text5.Text = NedgeNOuse
End If
End If
Next j35
For j36 = 0 To MaxNedge
LnowX = STedge(j36).dot1.X: LnowY = STedge(j36).dot1.Y
RnowX = STedge(j36).dot2.X: RnowY = STedge(j36).dot2.Y
WAC = Abs(LnowX - A3.X) + Abs(LnowY - A3.Y) + Abs(RnowX - C3.X) + Abs(RnowY - C3.Y)
If WAC Esp5 Then '找到原来位置,修改原来的基线,修改可用边数
' MsgBox "1-3"
If STedge(j36).sign = True Then
' MsgBox " 第6条基线原来用过,现在未用了,修改 "
STedge(MaxNedge + 6).sign = True
NedgeNOuse = NedgeNOuse - 1
' MsgBox "change"
End If
End If
Next j36
MaxNedge = MaxNedge + 6
End Sub
Public Sub DrawTriangle(D1 As dot, D2 As dot, D3 As dot) ' 画线
Form1.Pic1.Line (D1.X, D1.Y)-(D2.X, D2.Y), RGB(0, 100, 255)
Form1.Pic1.Line (D2.X, D2.Y)-(D3.X, D3.Y), RGB(0, 100, 255)
Form1.Pic1.Line (D3.X, D3.Y)-(D1.X, D1.Y), RGB(0, 100, 255)
End Sub
Public Sub Delaunay(F2 As dot, S2 As dot)
Dim T2 As dot
Dim jm As Integer
Dim Esp6 As Double
Dim wx As Double
Esp6 = 0.0000001
For jm = 0 To MaxNedge
wx = Abs(F2.X - STedge(jm).dot1.X) + Abs(F2.Y - STedge(jm).dot1.Y) + Abs(S2.X - STedge(jm).dot2.X) + Abs(S2.Y - STedge(jm).dot2.Y)
If wx Esp6 Then
If STedge(jm).sign = True Then
Exit Sub
End If
End If
Next jm
If GetThirdDot(F2, S2).JJ = True Then
T2 = GetThirdDot(F2, S2).DD
Call DrawTriangle(F2, S2, T2)
Call Deal3Dot(F2, S2, T2)
'Ntriangle = Ntriangle + 1
'Form1.TexNtri.Text = Ntriangle
Call StoreTriangle(F2, S2, T2)
Else
Call Deal2Dot(F2, S2)
Exit Sub
End If
Call Delaunay(F2, T2)
Call Delaunay(T2, S2)
Call Delaunay(S2, F2)
End Sub
Public Sub StoreTriangle(F3 As dot, S3 As dot, T3 As dot)
Ntriangle = Ntriangle + 1
STtriangle(Ntriangle).A = F3
STtriangle(Ntriangle).B = S3
STtriangle(Ntriangle).C = T3
End Sub
Public Sub DrawContour(Tri As triangle, Ho As Integer)
Dim A4 As dot
Dim B4 As dot
Dim C4 As dot
Dim Node1 As dot
Dim Node2 As dot
Dim HA4, HB4, HC4 As Double
Dim Esp6 As Double
Esp6 = 0.0000001
Node1.Z = Ho
Node2.Z = Ho
A4 = Tri.A: B4 = Tri.B: C4 = Tri.C
HA4 = Tri.A.Z: HB4 = Tri.B.Z: HC4 = Tri.C.Z
If HA4 - Ho > Esp6 And HB4 - Ho > Esp6 And HC4 - Ho > Esp6 Then
Exit Sub
End If
If Ho - HA4 > Esp6 And Ho - HB4 > Esp6 And Ho - HC4 > Esp6 Then
Exit Sub
End If
If (Abs(HA4 - HB4) * Abs(HB4 - HC4) * Abs(HC4 - HA4)) > Esp6 Then
If (HA4 - Ho) * (HB4 - Ho) > 0 Then
Node1.X = C4.X - ((C4.X - B4.X) * (HC4 - Ho) / (HC4 - HB4))
Node1.Y = C4.Y - ((C4.Y - B4.Y) * (HC4 - Ho) / (HC4 - HB4))
Node2.X = C4.X - ((C4.X - A4.X) * (HC4 - Ho) / (HC4 - HA4))
Node2.Y = C4.Y - ((C4.Y - A4.Y) * (HC4 - Ho) / (HC4 - HA4))
ElseIf (HB4 - Ho) * (HC4 - Ho) > 0 Then
Node1.X = A4.X - ((A4.X - C4.X) * (HA4 - Ho) / (HA4 - HC4))
Node1.Y = A4.Y - ((A4.Y - C4.Y) * (HA4 - Ho) / (HA4 - HC4))
Node2.X = A4.X - ((A4.X - B4.X) * (HA4 - Ho) / (HA4 - HB4))
Node2.Y = A4.Y - ((A4.Y - B4.Y) * (HA4 - Ho) / (HA4 - HB4))
ElseIf (HB4 - Ho) * (HA4 - Ho) > 0 Then
Node1.X = B4.X - ((B4.X - A4.X) * (HB4 - Ho) / (HB4 - HA4))
Node1.Y = B4.Y - ((B4.Y - A4.Y) * (HB4 - Ho) / (HB4 - HA4))
Node2.X = B4.X - ((B4.X - C4.X) * (HB4 - Ho) / (HB4 - HC4))
Node2.Y = B4.Y - ((B4.Y - C4.Y) * (HB4 - Ho) / (HB4 - HC4))
Else
End If
Form1.Pic1.Line (Node1.X, Node1.Y)-(Node2.X, Node2.Y)
End If
End Sub