You are on page 1of 14

3D drawing in Visual Basic

1 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

WebZIP lets you download complete Web pages or Web sites onto your hard
disk..Use WebZIP to get a permanent copy of online news articles, e-zines and
other research material, and quickly find a view them offline anytime.

WebZIP News
Upgrade
Don't Show Ads

September 1998

3D drawing in Visual Basic


by Norm Bowler
You can download this article's sample files from our Web site as part of the file sept98.zip. Go to
www.zdjournals.com/ivb, then click the Source Code hyperlink.
If you asked me whether or not Visual Basic was a great multimedia platform, my answer would be, "Yes, but not right
out of the box." Even with the Media Control Interface (MCI) object that comes in the professional versions of
VB 4 and 5, and the GIF and JPG format support in version 5, Visual Basic still lacks many of the features that would
make it a first-class multimedia delivery platform. Getting better support for images, animation, and 3D rendering will
cost you--either your time (spent writing custom functions in VB or Windows C) or your money (spent on prepackaged
libraries and controls to do the cool stuff). If it's cool you want, we can at least save you some time. In this article, we'll
introduce you to the concepts behind 3D drawing. Then, we'll walk you through a straightforward technique that draws
3D lines in a VB picture box, like those shown in Figure A. Next month, we'll demonstrate how to draw 3D wireframes
and filled shapes. Once you have our code in hand, you can use it to build custom 3D graphs, plots, and illustrations.
Let's begin by reviewing some fundamental aspects of 3D space that are integral to this process.
Figure A: We'll show you how to draw lines that look three-dimensional.

Through the looking glass


In order to make a picture box act like a window into a three-dimensional space, you'll have to use some sort of
perspective. Toward this end, you'll define a vanishing point in the picture box. Then, you'll write an algorithm that
displaces points toward the vanishing point as they move away from the viewer. (If you find this terminology unfamiliar,
you'll want to read the article "Simple Perspective" in this month's issue.)
Of course, as soon as you start thinking of a VB picture box as a window into 3D space, you'll need a coordinate
system to describe what you see and draw. The coordinate system will be familiar to algebra students: The origin--the
(0,0,0) point--will lie in the lower-left corner of the picture box. X values increase as they move to the right and Y values
increase as they move up. For the third dimension, you'll use Z, which increases as it moves away from the viewer
into the depths of the monitor. The plane of the box itself, which represents the viewer's location, has a Z value of 0.
Figure B shows an example that uses this coordinate system. The lower-left corner of the picture box has the (X, Y, Z)
coordinates (0, 0, 0); the lower-right corner lies at (100, 0, 0); the upper-left corner has the coordinates (0, 100, 0); and
the upper-right corner is at (100, 100, 0). The figure also shows the vanishing point in the center of the picture box,
with coordinates

03/12/2014 17.34

3D drawing in Visual Basic

2 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

(X, Y, 1000). Note that we use the variables X and Y instead of numbers because the vanishing point represents all
values of X and Y where Z equals 1000. We've positioned the point in the center of the picture box as if its X and Y
coordinates were (50, 50).
Figure B: Our coordinate system acts as a window into 3D space.

The most interesting part of Figure B is the line that runs from the lower-right corner (100, 0, 0) to the vanishing point
(X, Y, 1000). This is the line of convergence that represents all Z values between 0 and 1000 for points with an X, Y
coordinate of (100, 0). Our figure demonstrates that in order to draw a point in perspective, you simply determine
where it lies on the line between the vanishing point and the point's (X, Y) location on the picture box plane where Z
equals 0.
Now that you see the line on which the point must fall, the question becomes where on the line of convergence do you
place a particular point? This is where my ambition exceeds my mathematical understanding; but I've developed an
algorithm that looks good and appears to make sense. Let's see how it works.

An angular algorithm
The rate of change in an object's apparent position is greatest near the viewer and becomes progressively less as the
objects recede into the distance. So, making the amount of convergence directly proportional to its Z displacement
won't work. Instead, our algorithm translates a point's convergence back from the vanishing point, proportional to the
square of its Z travel over the distance between the vanishing point and the plane of the picture box. What a mouthful!
Here's how it works, in practical terms, using the coordinate system shown in Figure B.
Any point with a Z value greater than or equal to the vanishing point distance (1000) will be shown at the
vanishing point.
A point with a Z value of 900 has traveled 10 percent of the distance between the vanishing point (Z equal
to1000) and the picture box Z plane (Z equal to 0). Ten percent (.10) squared equals .01, or 1 percent. So, a
point at Z equal to 900 will be translated 1 percent along the line between the vanishing point and the point on
the picture box plane. Using similar calculations, points with Z values of 500, 100, and 0 will appear at 25
percent (.50 squared), 81 percent (.90 squared) and 100 percent (1.0 squared), respectively, of the distance
from the vanishing point along the line of convergence, respectively.
A point with a Z value of -100 has traveled 110 percent of the distance from the vanishing point to the picture
box plane. Squaring 1.10 yields 1.21, so the point will be translated 121 percent along the line of convergence.
Notice that the algorithm lets you calculate translated coordinates for points that are behind the viewer's plane of
vision. You'll need to do this to draw lines with one or more end points offscreen.
As you can see from our examples, the algorithm appears to fit reality. The 10 percent of Z travel nearest the picture

03/12/2014 17.34

3D drawing in Visual Basic

3 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

box plane converges 18 percent, while the 10 percent of Z travel nearest the vanishing point converges only 1 percent.

Setup code
Now, let's transform what you've learned about perspective drawing into a sample form and VB code. You'll implement
3D drawing using global variables and code attached to the form. (Packaging the code in a class library would be more
elegant, but doing so would add significantly to the size of the code and the scope of this article.) We'll begin work on
the project this month and add to it next month. To begin, open a new VB project. Name the default form frm3d, and
place on it a picture box named pb and a button named basic. Assign captions as shown in Figure C. Save the form as
threedee.frm and the project as threedee.vbp. Next you'll add the code.
Figure C: Add a picture box and a button to a form in a new project.

Note: Comment reduction


Because of the length of our example's code, we've omitted many of the comment lines. However, the sample
files available at www.zdjournals.com/ivb contain comprehensive comments.
Declarations
Listing A contains the global variable declarations you need to enter into frm3d. Most of these variables have to do
with implementing the coordinate system and vanishing point; they contain values calculated from the picture
box's properties during coordinate setup.
Listing A: Global variable declarations
Option Explicit
'window configuration -- pbl left (xmin),
`pbr right (xmax), pbb bottom (ymin),
`pbt top (ymax), pbz z coord
Dim pbl As Double
Dim pbr As Double
Dim pbb As Double
Dim pbt As Double
Dim pbz As Double
'vanishing point -- x,y,z coordinates
Dim vpx As Double
Dim vpy As Double

03/12/2014 17.34

3D drawing in Visual Basic

4 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

Dim vpz As Double


'zdelta -- z distance from pb plane
'to vanishing point
Dim zd As Double
Coordinate setup
The subprocedure init3d shown in Listing B initializes most of the global variables; add this code to your form. This
procedure lets you specify the X coordinate of the left side of the picture box, the Y coordinate of the bottom edge,
the width of the picture box, its Z coordinate, and how far into the scene the vanishing point lies. For the
coordinate system displayed in Figure B, the call would be as follows:
init3d 0, 0, 100, 0, 1000
Our example form makes this call in its Load event code, shown at the end of Listing B.
Listing B: init3d and Form_Load subprocedures
Sub init3d(l As Double, b As Double, w As Double, z As Double, vpoff As Double)
'l = left = x minimum. b = bottom = y minimum.
'w = width. l+w = x maximum. z = z of picture box plane.
vpoff = vanishing point z offset.
'Initializes vars that implement coordinate system.
`Sets a custom scale on picture box.
'picture box height and width, in pixels
Dim pbhpx As Single
Dim pbwpx As Single
pb.ScaleMode = 3 'pixels
pbhpx = pb.ScaleHeight
pbwpx = pb.ScaleWidth
'set coordinates for window
pbl = l
pbr = l + w
pbt = b + ((pbhpx / pbwpx) * w)
pbb = b
pbz = z
'set picturebox scale
pb.ScaleLeft = pbl
pb.ScaleTop = pbt
pb.ScaleWidth = pbr - pbl
pb.ScaleHeight = pbb - pbt
zd = vpoff
'init vanishing pt coords, centered horiz vert
vpx = (pbl + pbr) * (0.5)
vpy = ((pbt - pbb) * (0.5)) + pbb
vpz = pbz + zd
End Sub

Private Sub Form_Load()


'initialize coordinate system
init3d 0, 0, 100, 0, 1000
End Sub
The init3d procedure sets a custom scale for the picture box and calculates the maximum Y value for correct
aspect ratio. If you specify a width of 100 units and your picture box is half as high as it is wide, the maximum Y
value will be 50. Thus, squares will always be square.

03/12/2014 17.34

3D drawing in Visual Basic

5 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

The arguments to init3d allow you to set a different coordinate system than the one we're using, as well as making
the perspective effect more or less obvious. Our vanishing point is 10 times the width of the picture box.
Decreasing the Z offset would make the perspective effect more noticeable, which is similar to the look
produced by a wide-angle lens.
The code also places the vanishing point in the center of the image. If you wish to move the vanishing point and
horizon line higher on the screen, increase the up/down multiplier. Values greater than .5 raise the vanishing
point and make it appear that you're looking down on the scene, rather than looking parallel to the ground.
3D lines
Normally in VB, you'd draw a line in a picture box (pb) by specifying the X and Y coordinates of the endpoints, like
this:
pb.Line (x1, y1)-(x2, y2)
To draw in 3D, on the other hand, you need a Z coordinate as well. Enter into frm3d the subprocedure ln3d, shown
in Listing C, whose call is as follows:
ln3d x1, y1, z1, x2, y2, z2
Let's see how this subprocedure works.
Listing C: ln3d subprocedure and called functions
Sub ln3d(ByVal x1 As Double, ByVal y1 As Double, ByVal z1 As Double, ByVal x2 As Double, _
ByVal y2 As Double, ByVal z2 As Double)
`Draws a perspective corrected line
Dim xa As Double
Dim ya As Double
Dim xb As Double
Dim yb As Double
xa = xtrans(x1, z1)
ya = ytrans(y1, z1)
xb = xtrans(x2, z2)
yb = ytrans(y2, z2)
pb.Line (xa, ya)-(xb, yb)
End Sub

Function xtrans(ByVal x As Double, ByVal z As Double) As Double


`Translates 3D x coordinate into 2D picture box
`coordinate based on its z displacement
Dim zs As Double
Dim cp As Double
Dim sd As Double

'z scratch
'correction percentage
'scratch delta

If z >= vpz Then


xtrans = vpx
Exit Function
Else
zs = vpz - z
cp = (zs / zd) * (zs / zd)
sd = vpx - x
xtrans = vpx - (cp * sd)
End If
End Function

Function ytrans(ByVal y As Double, ByVal z As Double) As Double

03/12/2014 17.34

3D drawing in Visual Basic

6 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

`Translates 3D y coordinate into 2D picture box


`coordinate based on its z displacement
Dim zs As Double
Dim cp As Double
Dim sd As Double

'z scratch
'correction percentage
'scratch delta

If z >= vpz Then


ytrans = vpy
Exit Function
Else
zs = vpz - z
cp = (zs / zd) * (zs / zd)
sd = vpy - y
ytrans = vpy - (cp * sd)
End If
End Function
Translation functions
The actual line that the ln3d procedure will draw in the picture box will be a 2D (X,Y) line--in fact, it will call pb.Line
to do the job.
But first, it must calculate the convergence of the 3D coordinates and translate them into 2D
coordinates using the algorithm we described earlier. To perform this chore, ln3d calls the procedures xtrans and
ytrans, as shown in Listing C; add them to your form.
Line function
The ln3d procedure declares four variables to contain the translated
(x1, y1) - (x2, y2)
endpoints, it calls xtrans and ytrans to perform the calculation, and it calls pb.Line to draw the line. To set the color
and width of the line, modify the ForeColor and DrawWidth properties of the picture box.
An example
To see 3D line drawing in action, place the code from Listing D in the Click event of the Basic 3D Drawing button.
When you run the project, it will generate the lines shown in Figure A.
Private Sub basic_Click()
'loop counter
Dim lp As Double
'initialize picture box
vpy = (pbt + pbb) / 2
pb.Cls
pb.ForeColor = QBColor(0)
pb.FillStyle = 0
pb.FillColor = QBColor(11)
pb.DrawWidth = 1
'constants used to draw floor grid
Const xmin = -3000#
Const xmax = 3000#
Const zmin = 0#
Const zmax = 1000#
Const gstep = 50#
'horizon line
pb.Line (pbl, vpy)-(pbr, vpy)
'x lines
For lp = xmin To xmax Step gstep

03/12/2014 17.34

3D drawing in Visual Basic

7 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

ln3d lp, 0, zmin, lp, 0, zmax


DoEvents
Next lp
'z lines
For lp = zmin To zmax Step gstep
ln3d xmin, 0, lp, xmax, 0, lp
DoEvents
Next lp
pb.ForeColor = RGB(0, 0, 0)
End Sub
You can download this article's sample files from our Web site as part of the file oct98.zip. Go to
www.zdjournals.com/ivb,
then click the Source Code hyperlink.
This month, we'll expand our project to draw 3D spheres, cubes, and triangles, as well as filled wireframeshapes
like that shown in Figure A. We'll build on the code we wrote last month, and we assume you've either
downloaded or created the sample project.
Figure A: Nifty 3D images like this one will add sophistication to your applications.

Setup steps
At present, the threedee form in the threedee project contains a picture box to display 3D drawings and a single
command button. Let's begin by opening the project and adding two more buttons named filled and unfilled. Give
these buttons the captions Filled Wireframe and Unfilled Wireframe. Now we'll get to work drawing 3D cubes and
spheres.
3D cubes and spheres
Your first new 3D shape is a wireframe cube. Our cube procedure, shown in Listing A, uses the ln3d procedure we
presented last month to draw a rectangular prism. It takes minimum and maximum X, Y, and Z values as
arguments, then draws the 12 three-dimensional lines required to make a cube. (As with last month's code, we've
removed most comment lines to save space. However, the sample files contain comprehensive comments.)
Listing A: The cube procedure
Sub cube(ByVal xmin As Double, ByVal xmax As _
Double, ByVal ymin As Double, ByVal ymax As _
Double, ByVal zmin As Double, ByVal zmax As Double)
ln3d xmin, ymin, zmax, xmax, ymin, zmax 'back face

03/12/2014 17.34

3D drawing in Visual Basic

8 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

ln3d xmin, ymin, zmax, xmin, ymax, zmax


ln3d xmax, ymin, zmax, xmax, ymax, zmax
ln3d xmin, ymax, zmax, xmax, ymax, zmax
ln3d xmin, ymin, zmax, xmin, ymin, zmin 'side edges
ln3d xmax, ymin, zmax, xmax, ymin, zmin
ln3d xmin, ymax, zmax, xmin, ymax, zmin
ln3d xmax, ymax, zmax, xmax, ymax, zmin
ln3d xmin, ymin, zmin, xmax, ymin, zmin 'front face
ln3d xmin, ymin, zmin, xmin, ymax, zmin
ln3d xmax, ymin, zmin, xmax, ymax, zmin
ln3d xmin, ymax, zmin, xmax, ymax, zmin
End Sub
Next, you'll enter the code to create a sphere. Because this implementation doesn't perform shading, representing
a sphere is simply a matter of drawing a circle with a translated center point and a perspective-corrected radius.
Enter into the frm3d form the sp3d subprocedure shown in Listing B, which takes four arguments: the X, Y, and Z
coordinate of its center, and its radius:
sp3d x, y, z, radius
Listing B: The sp3d subprocedure
Sub sp3d(ByVal x1 As Double, ByVal y1 As Double, ByVal z1 As Double, ByVal r As Double)
Dim xa As Double
Dim ya As Double
Dim xb As Double
Dim cr As Double

'translated x
'translated y
'translated x for radius
'corrected radius length

xa = xtrans(x1, z1)
ya = ytrans(y1, z1)
xb = xtrans(x1 + r, z1)
cr = xb - xa
pb.Circle (xa, ya), cr
End Sub
The procedure uses xtrans and ytrans we created last month to translate the 3D center point to a 2D coordinate,
then adds the radius to the X coordinate of the center point to calculate a point on the right edge of the circle. The
difference between the two translated X coordinates is the perspective-corrected radius.
VB determines the circle's line width and color from the picture box's DrawWidth and ForeColor properties.
Similarly, the fill style and color come from the picture box's FillStyle and FillColor properties.
Let's update the code in the Basic 3D drawing button to display 3D cubes and spheres as well as lines, as shown
in Figure B. Add the code shown in color in Listing C at the beginning and end of the Basic 3D Drawing button's
Click event.
Figure B: Our code generates these sample spheres, cubes, and lines.

03/12/2014 17.34

3D drawing in Visual Basic

9 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

Listing C: basic_click()
Private Sub basic_Click()
Dim lp As Double
Dim ra(1 To 8, 1 To 3) As Double
Dim lp2 As Integer
Dim x As Integer
Dim y As Integer
Dim z As Integer
.
.
.
For lp = 700 To 100 Step -100 'spheres
sp3d 0, 10, lp, 10
DoEvents
Next lp
pb.ForeColor = QBColor(12) `cubes
For lp = 0 To 900 Step 100
cube 140, 180, 100, 140, lp, lp + 40
DoEvents
Next lp
pb.ForeColor = RGB(0, 0, 0)
End Sub
3D filled triangles
For your final primitive shape, you'll create filled and unfilled 3D triangles. But first, you must make a couple of
additions to the existing code. Add the following line to the global variables in the form's general declarations:
Dim spr As Double
This variable provides a scale unit-to-pixel ratio for the triangle fill you'll create later. Now, add this line to the init3d
procedure:
spr = (pbt - pbb) / pbhpx
This code calculates the ratio you just defined. The code for the tr3d procedure appears in Listing D, along with the
code for simple min and max functions the procedure uses. The tr3d procedure takes as arguments the X, Y, and
Z coordinates of the three corners:
tr3d x1, y1, z1, x2, y2, z2, x3, y3, z3

03/12/2014 17.34

3D drawing in Visual Basic

10 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

Listing D: The tr3d procedure

Sub tr3d(ByVal x1 As Double, ByVal y1 As Double, _


ByVal z1 As Double, ByVal x2 As Double, _
ByVal y2 As Double, ByVal z2 As Double, _
ByVal x3 As Double, ByVal y3 As Double, _
ByVal z3 As Double)
Dim xa As Double 'translated coords for 3 points
Dim ya As Double
Dim xb As Double
Dim yb As Double
Dim xc As Double
Dim yc As Double
Dim cury As Double 'current y
Dim ymin As Double 'minimum y for triangle
Dim ymax As Double 'max y for triangle
Dim xmin As Double 'min x for scan line
Dim xmax As Double 'max x for scan line
Dim stp As Double 'y step value
Dim b As Boolean 'boolean flag for line comparison
Dim iy As Double 'scratch vars for line comparison
Dim ay As Double
Dim ix As Double
Dim ax As Double
Dim xtmp As Double 'x intercept on current line
'if dens > 1, scan line step will be <1 pixel
'if dens = .5 step will be 2 pixels, etc.
Const dens = 1.1
xa = xtrans(x1, z1)
ya = ytrans(y1, z1)
xb = xtrans(x2, z2)
yb = ytrans(y2, z2)
xc = xtrans(x3, z3)
yc = ytrans(y3, z3)
If pb.FillStyle = 1 Then 'not filled. _
draw edge lines and exit
pb.Line (xa, ya)-(xb, yb)
pb.Line (xa, ya)-(xc, yc)
pb.Line (xb, yb)-(xc, yc)

Exit Sub
End If
ymin = min(ya, yb) 'scan line fill. _
Horizontal lines only.
ymin = min(ymin, yc)
ymax = max(ya, yb)
ymax = max(ymax, yc)
If ymin < min(pbb, pbt) Then ymin = min(pbb, pbt)
If ymax > max(pbb, pbt) Then ymax = max(pbb, pbt)
stp = spr / dens
For cury = ymin To ymax Step stp _
'scan from top to bottom
b = False 'determine whether to assign or compare
iy = min(ya, yb) 'line1: a-b. Set min/max x and y.
If iy = ya Then

03/12/2014 17.34

3D drawing in Visual Basic

11 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

ay = yb
ix = xa
ax = xb
Else
ay = ya
ix = xb
ax = xa
End If
If (cury >= iy) And (cury <= ay) Then
xtmp = ix + ((ax - ix) * ((cury - iy) / _
(ay - iy)))
xmin = xtmp
xmax = xtmp
b = True
End If
iy = min(ya, yc)
If iy = ya Then
ay = yc
ix = xa
ax = xc
Else
ay = ya
ix = xc
ax = xa
End If
If (cury >= iy) And (cury <= ay) Then
xtmp = ix + ((ax - ix) * ((cury - iy) / (ay - iy)))
If b Then
xmin = min(xtmp, xmin)
xmax = max(xtmp, xmax)
Else
xmin = xtmp
xmax = xtmp
End If
b = True
End If
iy = min(yb, yc)
If iy = yb Then
ay = yc
ix = xb
ax = xc
Else
ay = yb
ix = xc
ax = xb
End If
'if in y range
If (cury >= iy) And (cury <= ay) Then
xtmp = ix + ((ax - ix) * ((cury - iy) / (ay - iy)))
If b Then
xmin = min(xtmp, xmin)
xmax = max(xtmp, xmax)
Else
xmin = xtmp
xmax = xtmp
End If
End If
If (xmin >= min(pbl, pbr)) Or _
(xmax <= max(pbl, pbr)) Then
pb.Line (xmin, cury)-(xmax, cury), pb.FillColor
End If

03/12/2014 17.34

3D drawing in Visual Basic

12 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

Next cury
'outlines, just in case. (catches rounding errors)
pb.Line (xa, ya)-(xb, yb), pb.FillColor
pb.Line (xa, ya)-(xc, yc), pb.FillColor
pb.Line (xb, yb)-(xc, yc), pb.FillColor
End Sub

Function min(ByVal a As Double, ByVal b As Double)


If a < b Then
min = a
Else
min = b
End If
End Function

Function max(ByVal a As Double, ByVal b As Double)


If a > b Then
max = a
Else
max = b
End If
End Function
This procedure will draw either filled or unfilled triangles. If the picture box's FillStyle property is set to 1
(Transparent), the procedure translates the three endpoints, draws the three lines, and exits. If FillStyle is set to 0
(Solid) or any other value, the procedure draws a filled triangle in the picture box's fill color.
The filled triangle code uses a scan-line fill to fill a 2D triangle using only horizontal lines. The code determines the
minimum and maximum Y value of the three endpoints, then increments from one to the other in one-pixel
increments. At least two of the lines will have intersection points on each pixel row. All three lines will have a point
on a pixel row only when the triangle includes a horizontal line.
The code determines the intersection points, draws a horizontal line from the minimum X point to the maximum X
point, then continues to the next pixel row. When the code reaches the last Y value, it will have filled the triangle
using horizontal lines, with no unfilled pixels and no pixel filled more than once.
When developing this code, I noticed slight rounding errors that resulted in occasional unfilled pixels at the edge of
the triangle. I added a few lines of code to draw the triangle edges, but be aware that the result still misses a single
pixel once in a great while.
Beyond triangles
Filled triangles are the basis for all polygon fills. You can break down a rectangle into two triangles; more complex
shapes require more triangles. Our filled triangle procedure takes you out of the world of wireframe models and
a little bit closer to 3D rendering. If you're careful to draw your filled shapes in reverse Z-order (drawing the
farthest shape first), you can make your wireframe models opaque by performing hidden surface removal.
Figure A shows an example of a filled wireframe model. The lumps and swoops are the graph of the interaction of
two sine waves, varying along the X and Z axes. Listing E contains the wireframe1 procedure that yields this
result.
Listing E: The wireframe1 procedure
Sub wireframe1()
Dim x As Integer
Dim z As Integer
Const pi = 3.14159265
Const xmin = -400
Const xmax = 500
Const zmax = 800
Const zmin = 375
Const stp = 20 'grid size

03/12/2014 17.34

3D drawing in Visual Basic

13 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

Const fac1 = 250 'factor 1. sin rate of change


Const fac2 = 120 'factor 2. sin multiplier
Const fac3 = -170 'factor 3. grid y offset
pb.Cls
vpy = pbt 'set vanishing point to top of picture box
pb.FillColor = QBColor(11) 'set properties
pb.ForeColor = QBColor(0)
pb.DrawWidth = 1
For z = zmax To zmin Step (stp * -1) _
'draw from back to front
For x = xmin To xmax Step stp _
'draw from left to right
If (x < xmax) And (z > zmin) And _
(pb.FillStyle <> 1) Then
tr3d x, (Sin(x * pi / fac1) + Sin(z * pi / fac1)) _
* fac2 + fac3, z, x + stp, (Sin((x + stp) * pi / _
fac1) + Sin(z * pi / fac1)) * fac2 + fac3, z, x, _
(Sin(x * pi / fac1) + _
Sin((z - stp) * pi / fac1)) * fac2 + fac3, z - stp
tr3d x + stp, (Sin((x + stp) * pi / fac1) + _
Sin(z * pi / fac1)) * fac2 + fac3, z, x, _
(Sin(x * pi / fac1) + _
Sin((z - stp) * pi / fac1)) * fac2 + fac3, _
z - stp, x + stp, (Sin((x + stp) * pi / fac1) + _
Sin((z - stp) * pi / fac1)) * fac2 + fac3, z - stp
End If
If x < xmax Then
ln3d x, (Sin(x * pi / fac1) + Sin(z * pi / _
fac1)) * fac2 + fac3, z, x + stp, _
(Sin((x + stp) * pi / fac1) _
+ Sin(z * pi / fac1)) * fac2 + fac3, z
End If
If z > zmin Then
ln3d x, (Sin(x * pi / fac1) _
+ Sin(z * pi / fac1)) * fac2 _
+ fac3, z, x, (Sin(x * pi / fac1) _
+ Sin((z - stp) * pi / _
fac1)) * fac2 + fac3, z - stp
End If
DoEvents
Next x
Next z
End Sub
Miscellaneous functions
With the basic framework in place, it's easy to extend your 3D drawing capabilities. For instance, the sample code
available
from our Web site includes a simple extension. The horizon procedure takes "ground color" and "sky
color" as arguments. It clears the picture box, then colors everything above the vanishing point's Y value "sky" and
everything at or below the vanishing point "ground." You'll soon find yourself developing similar tools.
Stones left unturned
Is there really such a thing as a vanishing point? No--if there were, all the stars in the night sky would converge to
a single bright point. A vanishing point is just a convenient construction to use when implementing perspective,
and it works only when it lies beyond the farthest point you draw.
Also note that we didn't discuss color in these articles. Our sample code uses only the standard 16 colors available
through the qbcolor function, but you can use any colors. However, you may get strange results on 16- or
256-color systems, especially with line widths of 1.

03/12/2014 17.34

3D drawing in Visual Basic

14 di 14

http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...

Conclusion
After working through our examples, are you ready to write your own rendering engine? Probably not. But you're
bound to think of many ways to use the techniques we've demonstrated to deliver 3D graphs and wireframes in
your VB applications. We hope you'll use our examples as starting points to take your applications to the next
visual level.
1999 Microsoft Corporation. All rights reserved. Terms of use

thaivb@chaiyo.com

03/12/2014 17.34

You might also like