yfy2003 发表于 2004-5-14 23:57:00

[转帖]构建Delaunay三角网的VB源程序

Dim tPoints As Integer 'Variable for total number of points (vertices)


Private Sub Form_Load()<BR>'Initiate total points to 1, using base 0 causes problems in the functions<BR>tPoints = 1<BR>End Sub


Private Sub Picture1_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)


                       'variable to hold how many triangles are created by the triangulate function<BR>                       Dim HowMany As Integer<BR>                       <BR>                       'Set Vertex coordinates where you clicked the pic box<BR>                       Vertex(tPoints).x = x<BR>                       Vertex(tPoints).y = y<BR>                       <BR>                       'Perform Triangulation Function if there are more than 2 points<BR>                       If tPoints &gt; 2 Then<BR>                                                       'Clear the Picture Box<BR>                                                       Picture1.Cls<BR>                                                       'Returns number of triangles created.<BR>                                                       HowMany = Triangulate(tPoints)<BR>                       Else<BR>                                                       'Draw a circle where you clicked so it does something<BR>                                                       Picture1.Circle (Vertex(tPoints).x, Vertex(tPoints).y), 50, vbBlack<BR>                       End If<BR>                       <BR>                       'Increment the total number of points<BR>                       tPoints = tPoints + 1<BR>                       <BR>                       'Display the total points and total triangles<BR>                       lblPoints.Caption = "Points: " &amp; tPoints<BR>                       lblTris.Caption = "Triangles: " &amp; HowMany<BR>                       <BR>                       'Draw the created triangles<BR>                       For i = 1 To HowMany<BR>                                                       Picture1.Line (Vertex(Triangle(i).vv0).x, Vertex(Triangle(i).vv0).y)-(Vertex(Triangle(i).vv1).x, Vertex(Triangle(i).vv1).y)<BR>                                                       Picture1.Line (Vertex(Triangle(i).vv1).x, Vertex(Triangle(i).vv1).y)-(Vertex(Triangle(i).vv2).x, Vertex(Triangle(i).vv2).y)<BR>                                                       Picture1.Line (Vertex(Triangle(i).vv0).x, Vertex(Triangle(i).vv0).y)-(Vertex(Triangle(i).vv2).x, Vertex(Triangle(i).vv2).y)<BR>                       Next i


End Sub<BR>

yfy2003 发表于 2004-5-15 00:00:00

<BR>Option Explicit


'Points (Vertices)<BR>Public Type dVertex<BR>                       x As Long<BR>                       y As Long<BR>                       z As Long<BR>End Type


'Created Triangles, vv# are the vertex pointers<BR>Public Type dTriangle<BR>                       vv0 As Long<BR>                       vv1 As Long<BR>                       vv2 As Long<BR>End Type


'Set these as applicable<BR>Public Const MaxVertices = 500<BR>Public Const MaxTriangles = 1000


'Our points<BR>Public Vertex(MaxVertices) As dVertex


'Our Created Triangles<BR>Public Triangle(MaxTriangles) As dTriangle


Private Function InCircle(xp As Long, yp As Long, x1 As Long, y1 As Long, x2 As Long, y2 As Long, x3 As Long, y3 As Long, ByRef xc, ByRef yc, ByRef r) As Boolean<BR>                       'Return TRUE if the point (xp,yp) lies inside the circumcircle<BR>                       'made up by points (x1,y1) (x2,y2) (x3,y3)<BR>                       'The circumcircle centre is returned in (xc,yc) and the radius r<BR>                       'NOTE: A point on the edge is inside the circumcircle<BR>                                                               <BR>                       Dim eps As Double<BR>                       Dim m1 As Double<BR>                       Dim m2 As Double<BR>                       Dim mx1 As Double<BR>                       Dim mx2 As Double<BR>                       Dim my1 As Double<BR>                       Dim my2 As Double<BR>                       Dim dx As Double<BR>                       Dim dy As Double<BR>                       Dim rsqr As Double<BR>                       Dim drsqr As Double<BR>                       <BR>                       eps = 0.000001<BR>                       <BR>                       InCircle = False<BR>                                                                       <BR>                       If Abs(y1 - y2) &lt; eps And Abs(y2 - y3) &lt; eps Then<BR>                                                       MsgBox "INCIRCUM - F - Points are coincident !!"<BR>                                                       Exit Function<BR>                       End If<BR>                       <BR>                       If Abs(y2 - y1) &lt; eps Then<BR>                                                       m2 = -(x3 - x2) / (y3 - y2)<BR>                                                       mx2 = (x2 + x3) / 2<BR>                                                       my2 = (y2 + y3) / 2<BR>                                                       xc = (x2 + x1) / 2<BR>                                                       yc = m2 * (xc - mx2) + my2<BR>                       ElseIf Abs(y3 - y2) &lt; eps Then<BR>                                                       m1 = -(x2 - x1) / (y2 - y1)<BR>                                                       mx1 = (x1 + x2) / 2<BR>                                                       my1 = (y1 + y2) / 2<BR>                                                       xc = (x3 + x2) / 2<BR>                                                       yc = m1 * (xc - mx1) + my1<BR>                       Else<BR>                                                       m1 = -(x2 - x1) / (y2 - y1)<BR>                                                       m2 = -(x3 - x2) / (y3 - y2)<BR>                                                       mx1 = (x1 + x2) / 2<BR>                                                       mx2 = (x2 + x3) / 2<BR>                                                       my1 = (y1 + y2) / 2<BR>                                                       my2 = (y2 + y3) / 2<BR>                                                       xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2)<BR>                                                       yc = m1 * (xc - mx1) + my1<BR>                       End If<BR>                                                                       <BR>                       dx = x2 - xc<BR>                       dy = y2 - yc<BR>                       rsqr = dx * dx + dy * dy<BR>                       r = Sqr(rsqr)<BR>                       dx = xp - xc<BR>                       dy = yp - yc<BR>                       drsqr = dx * dx + dy * dy<BR>                       <BR>                       If drsqr &lt;= rsqr Then InCircle = True<BR>                                                       <BR>End Function<BR>Private Function WhichSide(xp As Long, yp As Long, x1 As Long, y1 As Long, x2 As Long, y2 As Long) As Integer<BR>                       'Determines which side of a line the point (xp,yp) lies.<BR>                       'The line goes from (x1,y1) to (x2,y2)<BR>                       'Returns -1 for a point to the left<BR>                       '                                                               0 for a point on the line<BR>                       '                                                       +1 for a point to the right<BR>                               <BR>                       Dim equation As Double<BR>                       <BR>                       equation = ((yp - y1) * (x2 - x1)) - ((y2 - y1) * (xp - x1))<BR>                       <BR>                       If equation &gt; 0 Then<BR>                                                       WhichSide = -1<BR>                       ElseIf equation = 0 Then<BR>                                                       WhichSide = 0<BR>                       Else<BR>                                                       WhichSide = 1<BR>                       End If


End Function

yfy2003 发表于 2004-5-15 00:02:00

Public Function Triangulate(nvert As Integer) As Integer<BR>                       'Takes as input NVERT vertices in arrays Vertex()<BR>                       'Returned is a list of NTRI triangular faces in the array<BR>                       'Triangle(). These triangles are arranged in clockwise order.<BR>                       <BR>                       Dim Complete(MaxTriangles) As Boolean<BR>                       Dim Edges(2, MaxTriangles * 3) As Long<BR>                       Dim Nedge As Long<BR>                       <BR>                       'For Super Triangle<BR>                       Dim xmin As Long<BR>                       Dim xmax As Long<BR>                       Dim ymin As Long<BR>                       Dim ymax As Long<BR>                       Dim xmid As Long<BR>                       Dim ymid As Long<BR>                       Dim dx As Double<BR>                       Dim dy As Double<BR>                       Dim dmax As Double<BR>                       <BR>                       'General Variables<BR>                       Dim i As Integer<BR>                       Dim j As Integer<BR>                       Dim k As Integer<BR>                       Dim ntri As Integer<BR>                       Dim xc As Double<BR>                       Dim yc As Double<BR>                       Dim r As Double<BR>                       Dim inc As Boolean<BR>                       <BR>                       'Find the maximum and minimum vertex bounds.<BR>                       'This is to allow calculation of the bounding triangle<BR>                       xmin = Vertex(1).x<BR>                       ymin = Vertex(1).y<BR>                       xmax = xmin<BR>                       ymax = ymin<BR>                       For i = 2 To nvert<BR>                                                       If Vertex(i).x &lt; xmin Then xmin = Vertex(i).x<BR>                                                       If Vertex(i).x &gt; xmax Then xmax = Vertex(i).x<BR>                                                       If Vertex(i).y &lt; ymin Then ymin = Vertex(i).y<BR>                                                       If Vertex(i).y &gt; ymax Then ymax = Vertex(i).y<BR>                       Next i<BR>                       dx = xmax - xmin<BR>                       dy = ymax - ymin<BR>                       If dx &gt; dy Then<BR>                                                       dmax = dx<BR>                       Else<BR>                                                       dmax = dy<BR>                       End If<BR>                       xmid = (xmax + xmin) / 2<BR>                       ymid = (ymax + ymin) / 2<BR>                       <BR>                       'Set up the supertriangle<BR>                       'This is a triangle which encompasses all the sample points.<BR>                       'The supertriangle coordinates are added to the end of the<BR>                       'vertex list. The supertriangle is the first triangle in<BR>                       'the triangle list.<BR>                       <BR>                       Vertex(nvert + 1).x = xmid - 2 * dmax<BR>                       Vertex(nvert + 1).y = ymid - dmax<BR>                       Vertex(nvert + 2).x = xmid<BR>                       Vertex(nvert + 2).y = ymid + 2 * dmax<BR>                       Vertex(nvert + 3).x = xmid + 2 * dmax<BR>                       Vertex(nvert + 3).y = ymid - dmax<BR>                       Triangle(1).vv0 = nvert + 1<BR>                       Triangle(1).vv1 = nvert + 2<BR>                       Triangle(1).vv2 = nvert + 3<BR>                       Complete(1) = False<BR>                       ntri = 1<BR>                       <BR>                       'Include each point one at a time into the existing mesh<BR>                       For i = 1 To nvert<BR>                                                       Nedge = 0<BR>                                                       'Set up the edge buffer.<BR>                                                       'If the point (Vertex(i).x,Vertex(i).y) lies inside the circumcircle then the<BR>                                                       'three edges of that triangle are added to the edge buffer.<BR>                                                       j = 0<BR>                                                       Do<BR>                                                                                       j = j + 1<BR>                                                                                       If Complete(j) &lt;&gt; True Then<BR>                                                                                                                       inc = InCircle(Vertex(i).x, Vertex(i).y, Vertex(Triangle(j).vv0).x, Vertex(Triangle(j).vv0).y, Vertex(Triangle(j).vv1).x, Vertex(Triangle(j).vv1).y, Vertex(Triangle(j).vv2).x, Vertex(Triangle(j).vv2).y, xc, yc, r)<BR>                                                                                                                       'Include this if points are sorted by X<BR>                                                                                                                       'If (xc + r) &lt; Vertex(i).x Then<BR>                                                                                                                                                       'complete(j) = True<BR>                                                                                                                       'Else<BR>                                                                                                                       If inc Then<BR>                                                                                                                                                       Edges(1, Nedge + 1) = Triangle(j).vv0<BR>                                                                                                                                                       Edges(2, Nedge + 1) = Triangle(j).vv1<BR>                                                                                                                                                       Edges(1, Nedge + 2) = Triangle(j).vv1<BR>                                                                                                                                                       Edges(2, Nedge + 2) = Triangle(j).vv2<BR>                                                                                                                                                       Edges(1, Nedge + 3) = Triangle(j).vv2<BR>                                                                                                                                                       Edges(2, Nedge + 3) = Triangle(j).vv0<BR>                                                                                                                                                       Nedge = Nedge + 3<BR>                                                                                                                                                       Triangle(j).vv0 = Triangle(ntri).vv0<BR>                                                                                                                                                       Triangle(j).vv1 = Triangle(ntri).vv1<BR>                                                                                                                                                       Triangle(j).vv2 = Triangle(ntri).vv2<BR>                                                                                                                                                       Complete(j) = Complete(ntri)<BR>                                                                                                                                                       j = j - 1<BR>                                                                                                                                                       ntri = ntri - 1<BR>                                                                                                                       End If<BR>                                                                                                                       'End If<BR>                                                                                       End If<BR>                                                       Loop While j &lt; ntri<BR>                       <BR>                                                       'Tag multiple edges<BR>                                                       'Note: if all triangles are specified anticlockwise then all<BR>                                                       'interior edges are opposite pointing in direction.<BR>                                                       For j = 1 To Nedge - 1<BR>                                                                                       If Not Edges(1, j) = 0 And Not Edges(2, j) = 0 Then<BR>                                                                                                                       For k = j + 1 To Nedge<BR>                                                                                                                                                       If Not Edges(1, k) = 0 And Not Edges(2, k) = 0 Then<BR>                                                                                                                                                                                       If Edges(1, j) = Edges(2, k) Then<BR>                                                                                                                                                                                                                       If Edges(2, j) = Edges(1, k) Then<BR>                                                                                                                                                                                                                                                       Edges(1, j) = 0<BR>                                                                                                                                                                                                                                                       Edges(2, j) = 0<BR>                                                                                                                                                                                                                                                       Edges(1, k) = 0<BR>                                                                                                                                                                                                                                                       Edges(2, k) = 0<BR>                                                                                                                                                                                                                               End If<BR>                                                                                                                                                                                               End If<BR>                                                                                                                                               End If<BR>                                                                                                                               Next k<BR>                                                                                       End If<BR>                                                       Next j<BR>                                                       <BR>                                                       'Form new triangles for the current point<BR>                                                       'Skipping over any tagged edges.<BR>                                                       'All edges are arranged in clockwise order.<BR>                                                       For j = 1 To Nedge<BR>                                                                                                                       If Not Edges(1, j) = 0 And Not Edges(2, j) = 0 Then<BR>                                                                                                                                                       ntri = ntri + 1<BR>                                                                                                                                                       Triangle(ntri).vv0 = Edges(1, j)<BR>                                                                                                                                                       Triangle(ntri).vv1 = Edges(2, j)<BR>                                                                                                                                                       Triangle(ntri).vv2 = i<BR>                                                                                                                                                       Complete(ntri) = False<BR>                                                                                                                       End If<BR>                                                       Next j<BR>                       Next i<BR>                       <BR>                       'Remove triangles with supertriangle vertices<BR>                       'These are triangles which have a vertex number greater than NVERT<BR>                       i = 0<BR>                       Do<BR>                                                       i = i + 1<BR>                                                       If Triangle(i).vv0 &gt; nvert Or Triangle(i).vv1 &gt; nvert Or Triangle(i).vv2 &gt; nvert Then<BR>                                                                                       Triangle(i).vv0 = Triangle(ntri).vv0<BR>                                                                                       Triangle(i).vv1 = Triangle(ntri).vv1<BR>                                                                                       Triangle(i).vv2 = Triangle(ntri).vv2<BR>                                                                                       i = i - 1<BR>                                                                                       ntri = ntri - 1<BR>                                                       End If<BR>                       Loop While i &lt; ntri<BR>                       <BR>                       Triangulate = ntri<BR>End Function

yfy2003 发表于 2004-5-15 00:05:00

原程序下载:


莫名 发表于 2004-5-18 13:04:00

好东西!

myfreemind 发表于 2004-5-18 23:56:00

Y兄继续~~:)

yeats 发表于 2004-5-27 10:11:00

太好了!


不知道怎么来感谢楼主

quanguang 发表于 2004-6-8 01:01:00

谢谢,楼主真是大好人!!楼主有什么需要帮忙的,尽管问,小弟一定尽力而为

z954134 发表于 2004-7-16 15:48:00

感谢啊

lmh 发表于 2004-10-28 13:12:00

无私的人!好东西!
页: [1] 2 3 4
查看完整版本: [转帖]构建Delaunay三角网的VB源程序