home *** CD-ROM | disk | FTP | other *** search
- VERSION 1.0 CLASS
- BEGIN
- MultiUse = -1 'True
- END
- Attribute VB_Name = "ObjGrid3D"
- Attribute VB_Creatable = False
- Attribute VB_Exposed = False
- Option Explicit
-
- Private xmin As Single ' Min X and Y values.
- Private Zmin As Single
- Private dx As Single ' Spacing between rows of data.
- Private dz As Single
- Private NumX As Integer ' Number of X and Y entries.
- Private NumZ As Integer
- Private Points() As Point3D ' Data values.
-
- Private RemoveHidden As Boolean ' Remove hidden surfaces?
-
- ' ************************************************
- ' Let the user decide if we should draw hidden
- ' surfaces.
- ' ************************************************
- Property Let ShowHidden(value As Boolean)
- RemoveHidden = Not value
- End Property
- ' ************************************************
- ' Tell the user if we are drawing hidden surfaces.
- ' ************************************************
- Property Get ShowHidden() As Boolean
- ShowHidden = Not RemoveHidden
- End Property
-
-
- ' ************************************************
- ' Draw a line between the points. Set the hi and
- ' lo values for the line.
- ' ************************************************
- Sub DrawAndSetLine(canvas As Object, ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single, hi() As Integer, lo() As Integer)
- Dim tmp As Single
- Dim ix As Integer
- Dim iy As Integer
- Dim y As Single
- Dim dy As Single
-
- ' Deal only with integers.
- x1 = CInt(x1)
- y1 = CInt(y1)
- x2 = CInt(x2)
- y2 = CInt(y2)
-
- ' Make x1 < x2.
- If x2 < x1 Then
- tmp = x1
- x1 = x2
- x2 = tmp
- tmp = y1
- y1 = y2
- y2 = tmp
- End If
-
- ' Draw the line.
- canvas.Line (x1, y1)-(x2, y2)
-
- ' Deal with vertical lines separately.
- If x1 = x2 Then
- If y1 < y2 Then
- lo(x1) = y1
- hi(x1) = y2
- Else
- lo(x1) = y2
- hi(x1) = y1
- End If
- Exit Sub
- End If
-
- ' Deal with non-vertical lines.
- dy = (y2 - y1) / CInt(x2 - x1)
- y = y1
- For ix = x1 To x2
- iy = CInt(y)
-
- lo(ix) = iy
- hi(ix) = iy
-
- y = y + dy
- Next ix
- End Sub
-
-
-
-
- ' ************************************************
- ' Draw a line between the points using and
- ' updating the hi and lo arrays.
- ' ************************************************
- Sub DrawLine(canvas As Object, ByVal x1 As Single, ByVal y1 As Single, ByVal x2 As Single, ByVal y2 As Single, hi() As Integer, lo() As Integer)
- Dim tmp As Single
- Dim ix As Integer
- Dim iy As Integer
- Dim y As Single
- Dim dy As Single
- Dim firstx As Integer
- Dim firsty As Integer
- Dim skipping As Boolean
- Dim above As Boolean
-
- ' Deal only with integers.
- x1 = CInt(x1)
- y1 = CInt(y1)
- x2 = CInt(x2)
- y2 = CInt(y2)
-
- ' Make x1 < x2.
- If x2 < x1 Then
- tmp = x1
- x1 = x2
- x2 = tmp
- tmp = y1
- y1 = y2
- y2 = tmp
- End If
-
- ' Deal with vertical lines separately.
- If x1 = x2 Then
- ' Make y1 < y2.
- If y2 < y1 Then
- tmp = y1
- y1 = y2
- y2 = tmp
- End If
- If y1 <= lo(x1) Then
- If y2 <= lo(x1) Then
- canvas.Line (x1, y1)-(x2, y2)
- Else
- canvas.Line (x1, y1)-(x2, lo(x2))
- End If
- lo(x1) = y1
- End If
- If y2 >= hi(x2) Then
- If y1 >= hi(x2) Then
- canvas.Line (x1, y1)-(x2, y2)
- Else
- canvas.Line (x1, hi(x1))-(x2, y2)
- End If
- hi(x2) = y2
- End If
- Exit Sub
- End If
-
- ' Deal with non-vertical lines.
- dy = (y2 - y1) / CInt(x2 - x1)
- y = y1
-
- ' Find the first visible point.
- skipping = True
- For ix = x1 To x2
- iy = CInt(y)
- ' See if this point is visible.
- If iy <= lo(ix) Then
- If skipping Then
- ' Start a new line below.
- skipping = False
- above = False
- firstx = ix
- firsty = lo(ix)
- End If
- ElseIf iy >= hi(ix) Then
- If skipping Then
- ' Start a new line above.
- skipping = False
- above = True
- firstx = ix
- firsty = hi(ix)
- End If
- Else
- ' This point is not visible.
- If Not skipping Then
- ' Draw the previous visible line.
- If above Then
- ' The line is coming from
- ' above. Connect it to hi(ix).
- canvas.Line (firstx, firsty)-(ix, hi(ix))
- Else
- ' The line is coming from
- ' below. Connect it to lo(ix).
- canvas.Line (firstx, firsty)-(ix, lo(ix))
- End If
-
- skipping = True
- End If
- End If
-
- If iy < lo(ix) Then lo(ix) = iy
- If iy > hi(ix) Then hi(ix) = iy
-
- y = y + dy
- Next ix
-
- ' Draw to the last point if necessary.
- If Not skipping Then _
- canvas.Line (firstx, firsty)-(x2, y2)
- End Sub
-
- ' ************************************************
- ' Create the Points array.
- ' ************************************************
- Sub SetBounds(x1 As Single, deltax As Single, xnum As Integer, z1 As Single, deltaz As Single, znum As Integer)
- Dim i As Integer
- Dim j As Integer
- Dim x As Single
- Dim z As Single
-
- xmin = x1
- Zmin = z1
- dx = deltax
- dz = deltaz
- NumX = xnum
- NumZ = znum
- ReDim Points(1 To NumX, 1 To NumZ)
-
- x = xmin
- For i = 1 To NumX
- z = Zmin
- For j = 1 To NumZ
- Points(i, j).coord(1) = x
- Points(i, j).coord(2) = 0
- Points(i, j).coord(3) = z
- Points(i, j).coord(4) = 1#
- z = z + dz
- Next j
- x = x + dx
- Next i
- End Sub
- ' ************************************************
- ' Save the indicated data value.
- ' ************************************************
- Sub SetValue(x As Single, y As Single, z As Single)
- Dim i As Integer
- Dim j As Integer
-
- i = (x - xmin) / dx + 1
- j = (z - Zmin) / dz + 1
- Points(i, j).coord(2) = y
- End Sub
-
- ' ***********************************************
- ' Return a string indicating the object type.
- ' ***********************************************
- Property Get ObjectType() As String
- ObjectType = "GRID"
- End Property
-
-
-
- ' ***********************************************
- ' Fix the data coordinates at their transformed
- ' values.
- ' ***********************************************
- Public Sub FixPoints()
- Dim i As Integer
- Dim j As Integer
- Dim k As Integer
-
- For i = 1 To NumX
- For j = 1 To NumZ
- For k = 1 To 3
- Points(i, j).coord(k) = Points(i, j).trans(k)
- Next k
- Next j
- Next i
- End Sub
-
- ' ************************************************
- ' Apply a transformation matrix which may not
- ' contain 0, 0, 0, 1 in the last column to the
- ' object.
- ' ************************************************
- Public Sub ApplyFull(M() As Single)
- Dim i As Integer
- Dim j As Integer
-
- For i = 1 To NumX
- For j = 1 To NumZ
- m3ApplyFull Points(i, j).coord, M, Points(i, j).trans
- Next j
- Next i
- End Sub
-
- ' ************************************************
- ' Apply a transformation matrix to the object.
- ' ************************************************
- Public Sub Apply(M() As Single)
- Dim i As Integer
- Dim j As Integer
-
- For i = 1 To NumX
- For j = 1 To NumZ
- m3Apply Points(i, j).coord, M, Points(i, j).trans
- Next j
- Next i
- End Sub
-
-
- ' ************************************************
- ' Apply a nonlinear transformation.
- ' ************************************************
- Public Sub Distort(D As Object)
- Dim i As Integer
- Dim j As Integer
-
- For i = 1 To NumX
- For j = 1 To NumZ
- D.Distort Points(i, j).coord(1), Points(i, j).coord(2), Points(i, j).coord(3)
- Next j
- Next i
- End Sub
-
- ' ************************************************
- ' Write a grid to a file using Write.
- ' Begin with "GRID" to identify this object.
- ' ************************************************
- Public Sub FileWrite(filenum As Integer)
- Dim i As Integer
- Dim j As Integer
-
- ' Write basic information.
- Write #filenum, _
- "GRID", xmin, Zmin, dx, dz, NumX, NumZ
-
- ' Write the Z values.
- For i = 1 To NumX
- For j = 1 To NumZ
- Write #filenum, Points(i, j).coord(2)
- Next j
- Next i
- End Sub
-
-
-
- ' ************************************************
- ' Draw the grid without hidden surfaces using the
- ' hi-lo algorithm.
- ' ************************************************
- Public Sub DrawWithoutHidden(canvas As Object, Optional r As Variant)
- Dim xmin As Integer
- Dim xmax As Integer
- Dim lo() As Integer
- Dim hi() As Integer
- Dim ix As Integer
- Dim i As Integer
- Dim j As Integer
-
- ' Bound the X values.
- xmin = Points(1, 1).trans(1)
- xmax = xmin
- For i = 1 To NumX
- For j = 1 To NumZ
- ix = CInt(Points(i, j).trans(1))
- If xmin > ix Then xmin = ix
- If xmax < ix Then xmax = ix
- Next j
- Next i
-
- ' Create the hi and lo arrays.
- ReDim lo(xmin To xmax)
- ReDim hi(xmin To xmax)
-
- ' Draw the X and Z front edges.
- For i = 2 To NumX
- ' Draw the edge between
- ' Points(i - 1, NumZ) and Points(i, NumZ)
- ' and set hi and lo for its values.
- DrawAndSetLine canvas, _
- Points(i - 1, NumZ).trans(1), _
- Points(i - 1, NumZ).trans(2), _
- Points(i, NumZ).trans(1), _
- Points(i, NumZ).trans(2), _
- hi, lo
- Next i
- For i = 2 To NumZ
- ' Draw the edge between
- ' Points(NumX, i - 1) and Points(NumX, i)
- ' and set hi and lo for its values.
- DrawAndSetLine canvas, _
- Points(NumX, i - 1).trans(1), _
- Points(NumX, i - 1).trans(2), _
- Points(NumX, i).trans(1), _
- Points(NumX, i).trans(2), _
- hi, lo
- Next i
-
- ' Draw the "rectangles."
- For i = NumX - 1 To 1 Step -1
- For j = NumZ - 1 To 1 Step -1
- ' Draw the edges between:
- ' Points(i, j) and Points(i + 1, j)
- ' Points(i, j) and Points(i, j + 1)
-
- ' If the right side of the "rectangle"
- ' leans over the top like this:
- ' +_
- ' | \_
- ' | \_
- ' + \_
- ' \ \
- ' +------+
- ' draw the top first so the right side
- ' doesn't make hi() too bit and stop
- ' the top from being drawn.
- '
- ' This only happens with perspective
- ' projection.
- If Points(i + 1, j).trans(1) >= Points(i, j).trans(1) Then
- DrawLine canvas, _
- Points(i, j).trans(1), _
- Points(i, j).trans(2), _
- Points(i, j + 1).trans(1), _
- Points(i, j + 1).trans(2), _
- hi, lo
- DrawLine canvas, _
- Points(i, j).trans(1), _
- Points(i, j).trans(2), _
- Points(i + 1, j).trans(1), _
- Points(i + 1, j).trans(2), _
- hi, lo
- Else
- DrawLine canvas, _
- Points(i, j).trans(1), _
- Points(i, j).trans(2), _
- Points(i + 1, j).trans(1), _
- Points(i + 1, j).trans(2), _
- hi, lo
- DrawLine canvas, _
- Points(i, j).trans(1), _
- Points(i, j).trans(2), _
- Points(i, j + 1).trans(1), _
- Points(i, j + 1).trans(2), _
- hi, lo
- End If
- Next j
- Next i
- End Sub
-
- ' ************************************************
- ' Draw the grid including hidden surfaces.
- ' ************************************************
- Public Sub DrawWithHidden(canvas As Object, Optional r As Variant)
- Dim i As Integer
- Dim j As Integer
-
- On Error Resume Next
-
- ' Draw lines parallel to the X axis.
- For i = 1 To NumX
- canvas.CurrentX = Points(i, 1).trans(1)
- canvas.CurrentY = Points(i, 1).trans(2)
- For j = 2 To NumZ
- canvas.Line -(Points(i, j).trans(1), _
- Points(i, j).trans(2))
- Next j
- Next i
-
- ' Draw lines parallel to the Y axis.
- For j = 1 To NumZ
- canvas.CurrentX = Points(1, j).trans(1)
- canvas.CurrentY = Points(1, j).trans(2)
- For i = 2 To NumX
- canvas.Line -(Points(i, j).trans(1), _
- Points(i, j).trans(2))
- Next i
- Next j
- End Sub
-
- ' ************************************************
- ' Draw the transformed points on a Form, Printer,
- ' or PictureBox.
- ' ************************************************
- Public Sub Draw(canvas As Object, Optional r As Variant)
- If RemoveHidden Then
- DrawWithoutHidden canvas, r
- Else
- DrawWithHidden canvas, r
- End If
- End Sub
-
-
-
- ' ************************************************
- ' Read a grid from a file using Input.
- ' Assume the "GRID" label has alreaDz been
- ' read.
- ' ************************************************
- Public Sub FileInput(filenum As Integer)
- Dim i As Integer
- Dim j As Integer
-
- ' Get the basic information.
- Input #filenum, xmin, Zmin, dx, dz, NumX, NumZ
-
- ' Allocate the Points array and set the X and
- ' Y values.
- SetBounds xmin, dx, NumX, Zmin, dz, NumZ
-
- ' Read the Z values.
- For i = 1 To NumX
- For j = 1 To NumZ
- Input #filenum, Points(i, j).coord(2)
- Next j
- Next i
- End Sub
-
-
-
-