Académique Documents
Professionnel Documents
Culture Documents
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
03/12/2014 17.34
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
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.
03/12/2014 17.34
4 di 14
http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...
03/12/2014 17.34
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
'z scratch
'correction percentage
'scratch delta
03/12/2014 17.34
6 di 14
http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...
'z scratch
'correction percentage
'scratch delta
03/12/2014 17.34
7 di 14
http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...
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
8 di 14
http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...
'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
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
10 di 14
http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...
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
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
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
03/12/2014 17.34
13 di 14
http://kampol.htc.ac.th/web1/subject/programming2/sheet/vb6/vbarticl...
03/12/2014 17.34
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