RogCAD history and hand-written derivations
-------------------------------------------
RogCAD home
RogCAD code - complete
RogCAD began life as a strictly text-output
CAD program in 1993.
I was designing a complicated structure which I had
proposed to build for a client, and I wanted to
present them with a perspective drawing on paper.
I soon discovered that there is no non-arbitrary
method for setting up perspective lines so as to
achieve a realistic camera's eye view.
I wished I had 3D CAD software, but the only
computer I owned at the time was an IBM 8088
with a monitor that could display only text,
so no commercial CAD software would have been
of any use even if I could have afforded such
software.
What to do. It occurred to me to try to write
a simple computer program that would output
raw data which could then be plotted on paper.
At first, it struck me as something that was way
beyond me. I knew enough math to appreciate how
messy things can get when you try to project a
three-dimensional object onto a floating
two-dimensional plane, that plane itself being
something that you must define mathematically.
But the problem kept tugging at me and I sat down
the next morning to task myself with it.
That night I had my first version ready for testing:
-------------------------------------------------------
1 REM DECK1.BAS
10 INPUT XS
12 INPUT YS
14 INPUT ZS
20 PRINT
30 X=(((150-XS)*(345-(2*YS)-ZS))+(XS*(250-ZS-(2*YS))))/
(700-(3*XS)-ZS-(2*YS))
[That value for X is then inserted
into equations that define Y and Z]
40 Y=(((100*X)-(YS*X)-(100*XS)+(YS*XS))/(150-XS))+YS
50 Z=(((50*X)-(ZS*X)-(50*XS)+(ZS*XS))/(150-XS))+ZS
[Those values for X, Y and Z are then
inserted into an equation to define M]
60 M=(((X-73.93)^2)+((Y-49.29)^2)+((Z-24.64)^2))^.5
70 PRINT M: REM magnitude
80 PRINT
[Those values for X, Y, Z and M are then
inserted into an equation to define C]
90 C=(((X-73.93)*(-.583))+((Y-49.29)*(-.392))+
((Z-24.64)*(2.533)))/(2.63*M)
100 PRINT
110 PRINT "ANGLE = ARCOS "C
120 END
-------------------------------------------------------
That first version was capable only of handling one
pre-selected perspective point and one pre-selected
focal point, and the program had to be run one time
for each data point of the proposed structure.
I selected 41 data points which represented
41 vertices on the proposed structure.
I ran the program and it supplied me with an angle
and a magnitude. I plotted the point on a piece
of paper and then ran the program another 40 times.
It was very exciting to see each plotted point land
at its expected spot on the paper. I connected the
points with a straight-edge. It was magical as the
outline of the structure appeared before my eyes.
(I then filled in the remaining architectural details
by way of visual extrapolation.)
The rest of the story is beneath these images of derivations:
Original notes and derivations for RogCAD, April 1993
pre-CAD planning sketch
The first nine images below are of the non-
generalized derivation (pre-defined perspective
point and focal point) of the floating image
plane and projection of a structure.
The second batch of nine images is of the
generalized derivation (variable perspective point
and focal point) which is much more complicated.
Vector cross-product is used to create a floating
image plane with a normal vector that passes
through the origin of the xyz axes.
Points on the structure are projected onto the
floating image plane. Vector dot-product is
used to test from which side of the z-axis each
projected point stems.
After the initial vector considerations, it's just
algebra. But the magic of algebra fascinates me,
especially when it goes on for many pages and it
actually works.
If you are using a laptop or desktop computer,
you might want to magnify this page to 150 percent.
Microsoft Edge browser users should click on the
three dots ... at the upper right-hand corner,
then use the "zoom" feature. Vertical three dots
for Chrome browser users.
Those derivations produced the original
program code for a specific
perspective point and focal point:
The program print-out on
the dot-matrix printer:
The first RogCAD output.
The points had to be plotted on paper,
as I had only an IBM XT with a text-only monitor:
Derivation of floating image plane and
projection of structure, generalized,
next nine images:
The generalized calculator kernel
print-out on the dot-matrix printer:
I took a very over-complicated approach to the
problem as a result of following a natural inclination
to mimic the real life situation -- I used vectors to
define an image plane floating in space, onto which an
object would be projected. This is messier than just
having a simple image plane defined on the X and Z
axis, using a simple trigonometric projection, then
rotating the object, which is how it's normally done.
But it never occured to me to do it the latter way
since the floating image plane directly simulates
the real-life situation of a person changing their
location (perspective point) in relation to a
stationary architectural object.
This approach turned out be fortuitous, since it
easily allows the user to specify a particular
perspective point in three dimensional space, as
well as a particular focal point (without me --
the software engineer -- having to work out some
set of hideous transformations). And that is well
suited to a user who likes or needs to take a
technical, accurate or analytical approach. It
also worked out well for the future of the software,
since it provided an easy way to upgrade it while
keeping track of shifting perspectives
and focal points. These were features I added
after I got my AT-286 computer with an EGA graphics
monitor in 1995.
The on-screen graphics provided by the 286 gave me
an environment where I could expand the software's
features endlessly. The program-code grew from
twelve lines to ten thousand lines, which is still
tiny by 3D CAD standards.
----
My first upgrade was to allow for user-specified
perspective and focal points at run-time, along
with the capacity to go inside a structure, which
greatly complicated the already complicated
calculator kernel which performs the image-projection.
Here is that upgraded image-projection program-code
(in a tidier format than the dot-matrix print-out above).
It's less than one percent of RogCAD's current
program code, but it's the most magical part.
For LN = FL(GB) To LL(GB)
1045 inc = 299
1050 If DT = 1 Then DT = 0: G = SP(LN): GoTo 1090
G = FP(LN): DT = 1
1070:
If ((X(G) * L) + (Y(G) * M) + (Z(G) * N)) >
((L * L) + (M * M) + (N * N)) Then GoTo 3070
If DT = 1 Then GoTo 1100
1090:
If ((X(G) * L) + (Y(G) * M) + (Z(G) * N)) >
((L * L) + (M * M) + (N * N)) Then GoTo 3120
1100:
W = ((A * A) + (B * B) + (C * C) -
(A * X(G)) - (B * Y(G)) - (C * Z(G)))
[ W is then the denominator in the
following three equations. ]
R(G) = (((A * I) * (A - X(G))) + (B * B * X(G)) + (C * C * X(G))
- (B * X(G) * Y(G)) - (C * X(G) * Z(G)) + ((B * J)
* (A - X(G))) + ((C * K) * (A - X(G))) - ((B * Y(G))
* (A - X(G))) - ((C * Z(G)) * (A - X(G)))) / W
S(G) = (((B * J) * (B - Y(G))) + (A * A * Y(G)) + (C * C * Y(G))
- (A * Y(G) * X(G)) - (C * Y(G) * Z(G)) + ((A * I)
* (B - Y(G))) + ((C * K) * (B - Y(G))) - ((A * X(G))
* (B - Y(G))) - ((C * Z(G)) * (B - Y(G)))) / W
T(G) = (((C * K) * (C - Z(G))) + (A * A * Z(G)) + (B * B * Z(G))
- (A * Z(G) * X(G)) - (B * Z(G) * Y(G)) + ((A * I)
* (C - Z(G))) + ((B * J) * (C - Z(G))) - ((A * X(G))
* (C - Z(G))) - ((B * Y(G)) * (C - X(G)))) / W
[ R(G), S(G) and T(G) are then inserted into
the following two equations. ]
U(G) = (((R(G) - L) ^ 2) + ((S(G) - M) ^ 2) +
((T(G) - N) ^ 2)) ^ 0.5
V(G) = (((R(G) - L) * (R(8001) - L)) +
((S(G) - M) * (S(8001) - M))
+ ((T(G) - N) * (T(8001) - N))) /
(U(G) * ((((R(8001) - L) ^ 2)
+ ((S(8001) - M) ^ 2) + ((T(8001) - N) ^ 2)) ^ 0.5))
[ U(G) and V(G) are then inserted into
the following equation. ]
XX(G) = U(G) * V(G)
If V(G) > 0.9999 Or V(G) < -0.9999 Then YY(G) = 0: GoTo 1200
YY(G) = U(G) * ((1 - ((V(G)) ^ 2)) ^ 0.5)
If ((L * S(G)) - (M * R(G))) < 0 Then YY(G) = (-1 * YY(G))
1200:
If CHK = 0 Then CHK = 1: GoTo 950
IF DT = 1 THEN X(G) = XR(G) - TX: Y(G) = YR(G) - TY
Z(G) = ZR(G) - TZ: GOTO 1050
END IF
X(G) = XR(G) - TX: Y(G) = YR(G) - TY: Z(G) = ZR(G) - TZ
1250:
GY(FP(LN)) = (MM * 15.2 * YY(FP(LN))) + 680 + HSH
GX(FP(LN)) = (MM * (-15.2) * XX(FP(LN))) + 430 - VSH
GY(SP(LN)) = (MM * 15.2 * YY(SP(LN))) + 680 + HSH
GX(SP(LN)) = (MM * (-15.2) * XX(SP(LN))) + 430 - VSH
If ICHK = 1 Then GoTo 1280
If READSWITCH = 1 Then GoTo 1290
1280:
viewport.Line (GY(FP(LN)), GX(FP(LN)))-(GY(SP(LN)), GX(SP(LN))),
RGB(redd(cdex), green(cdex), blue(cdex))
1290 Next LN
3070 :
INC = INC - 1
IF INC = 0 THEN INC = 299: DT = 0: X(G) = XR(G) - TX:
Y(G) = YR(G) - TY: Z(G) = ZR(G) - TZ: GX(FP(LN)) = 999:
GOTO 1290
X(G) = ((INC / 299) * (TEMX(G) - X(SP(LN)))) + X(SP(LN))
Y(G) = ((INC / 299) * (TEMY(G) - Y(SP(LN)))) + Y(SP(LN))
Z(G) = ((INC / 299) * (TEMZ(G) - Z(SP(LN)))) + Z(SP(LN))
GOTO 1070
3120 :
INC = INC - 1
IF INC = 0 THEN INC = 299: DT = 0: X(G) = XR(G) - TX:
Y(G) = YR(G) - TY: Z(G) = ZR(G) - TZ: GX(SP(LN)) = 999:
GOTO 1290
X(G) = ((INC / 299) * (TEMX(G) - X(FP(LN)))) + X(FP(LN))
Y(G) = ((INC / 299) * (TEMY(G) - Y(FP(LN)))) + Y(FP(LN))
Z(G) = ((INC / 299) * (TEMZ(G) - Z(FP(LN)))) + Z(FP(LN))
GOTO 1090
RogCAD code - complete
RogCAD home
|