3D Rotations

3D Rotations

About the time that I was doing my initial Mona Lisa graphics (approximately fall 1974), I was approached by an art student who wanted a program written to show a plexiglas cube with some internal divisions displayed in different rotations for some art project she had.  I had been wanting to do some sort of 3D rotation project of my own, so this was the perfect opportunity to do it since I was going to get paid.  All that fun, and money too!

Before being seduced by the dark side of computer programming, I had been studying to be an architect.  I wanted to be able to enter house plans and have the computer draw them from different perspectives.  Doing this 3D rotation project would give me the rudiments to start doing such things.

Some time during high school, I had gotten hold of a reprint of a Data Processing magazine article dated 1968 where the authors of the article had constructed one of the first flight simulators using a graphical display.  In the article they detailed the problems of three dimensional rotation and how to produce a visual representation of the output.  While they left out many of the technical issues, one of the things they did document was the 3D rotation multiplication matrix they used to rotate their data points.  I used that matrix as the core of my rotation routine.

In order to generate a three dimensional image, I had to first come up with a way to represent the object.  I chose simple line segments, producing what is known as a "wireframe" image.  Each line would consist of a start point in 3D space (X1, Y1, Z1) and an end point in 3D space  (X2, Y2, Z2).  This being the days of card punches and card readers, each card of the data deck would represent a line in 3D space.  I'd also add a comment on what feature the line segment was connected to.  (In addition to commenting my programs, I also comment my data.)

  X1 Y1 Z1      X2 Y2 Z2    COMMENT

Since many points would be in common, it didn't make much sense to store the data as an array of line segments.  Take for instance the corner of a cube, there are three lines that connect to the corner.  If I was going to be rotating these endpoints, it would be much more efficient to store the endpoints in a single array and then have a matching array of lines that referenced the endpoint indices.

So at image load, the program would read the data card containing the two endpoints of a line.  The program would then search the array of known endpoints for a matching value.  If found, the index of the point would be returned.  If not, a new entry would be added to the endpoint table and that new index would be returned.  The indices for the Start point and the End point would then be added to an array of line segments.

Index Endpoint
1 (1,1,-1)
2 (1,1,1)
3 (-1,1,1)
4 (-1,1,-1)
5 (1,-1,-1)
6 (1,-1,1)
7 (-1,-1,1)
8 (-1,-1,-1)
Index From  To 
1 1 2
2 1 4
3 1 5
4 2 3
5 2 6
6 3 4
7 3 7
8 4 8
9 5 6
10 5 8
11 6 7
12 7 8

When it came time to rotate the points, to save time, the Sine and Cosine of the rotation angles would be looked up and assigned to variables.  This meant that the calling of the slow transcendental math functions would occur only be once per rotation.

A secondary table of endpoints would be used to hold the rotated results from the original table.  This would prevent precision errors that would occur if we continuously rotated the rotated values.  Each rotation would be calculated from the original array and then stored in the results array.  The plotter routine would then walk the array of line segments and fetch the rotated, rather than the original, endpoint and position the pen accordingly.  Since this was a simple program, I dropped the calculated Z dimension and used only the X and Y values to position the plotter.  At this point I could have performed some further calculations to determine the offset that the Z dimension would have against the X and Y locations as plotted against the view from a location in 3D space (i.e. your eye).  But it would have involved a lot more processing and at the time I probably didn't understand the math involved.  Using a cribbed rotation matrix was my limit at that moment.

After I delivered the output of the program to the art student, I turned to how to use the program for my own purposes.  And yeah, she paid me for my efforts, $5.

While my initial desire was to use my new programming toy for architectural purposes, I realized the datasets for a house could get to be quite large and I had limited space.  I was also realizing the limits of wireframe drawings.  A house, while desirable, would result in a mess of lines drawn on top of each other.

Looking for a smaller project, I seized on the idea of making a dataset representing my prized possession, a Hewlett‑Packard HP‑65 pocket programmable calculator.  Why did I get the HP‑65?  I could have gotten two HP‑45's and had change left over for the same price.  I had become spoiled.  The Physics Department I worked at had an HP‑9100 desktop programmable calculator with a flatbed plotter attached.  Since I worked third shift, the majority of my jobs were long running processes on the Univac 418 computers (see the picture).  In fact, during my first weeks on the job, Pioneer 10 was just going past Jupiter and we were receiving tapes from NASA in what was called "high data rate".  Essentially my job was to mount a data tape, start a program, and find something to do for the next eight hours as the computer processed the data and generated 35mm microfilm plots of the data.  The only time the computer needed human intervention was to tell it to retry the occasional bad tape read.  The desktop calculator and plotter were located off the machine floor and I couldn't observe the computer from the cubicle it was in.  So I took a cheap AM radio and tuned it to a station setting that would let me hear the processor running.  Back then, there was no thought given to RF shielding and these beasts radiated a strong signal.  You could even tune a different setting to listen to the card readers and line printers if you wanted.  I would tune the radio so I could hear the processor grinding away in it's various subroutines (each had a distinct sound) and then go out of the computer room to the outer offices where it was warmer and the HP‑9100 was.  I'd place the radio on the conduit running through the offices and I could still hear the processor running, even though I was out of range of the radiated signal.  When the computer needed attention, it would print an error message on the operator's console (no CRTs back then) and then pause for input.  This would put the processor in a tight loop as it waited for user input.  When the sound of the radio changed from grinding noises to a high pitched whine, I knew the computer needed attention and I would go back to the machine floor to see what it needed.

So I learned to program the HP‑9100 calculator.  Later when Hewlett‑Packard announced a handheld programmable calculator, the HP‑65, I had to do some serious ponderings.  This was before the announcement of the Altair 8800 an Intel 8080 based microcomputer.  The thought of having a home computer was a long way down the road.  There had been stories of people who had purchased PDP‑8 computers for home use, but those systems cost on the other side of $5000.  I was doing a lot of math calculations for one reason or another and when it came down to the decision of getting a calculator that I would have to go punch, punch, punch for every calculation or entering a program and just going punch, the answer seemed easy.  I did look long and hard at the HP‑45, but the thought of having to do the same operations over and over, versus programming a calculator to do the calculations for me, made the decision easy, but expensive.  In the end, I programmed that little beasty to death, I have over 15 programs I authored in the Hewlett‑Packard User Library and I have hundreds I did not submit.  I still have it, even though I purchased the later calculators from HP, the HP‑67 (sold), HP‑41C, HP‑41CV (sold), HP‑41CX, HP‑48SX (stolen), and my current sidekick, the HP‑48GX.  I also have the HP‑75C that was given to me.  Not to mention the HP‑16C, the true computer programmer's calculator.  But those will be documented on a different page.

My HP‑65 was my constant companion (you can see it on my belt on the left) and after writing the 3D rotation program, it was readily at hand to measure and create a 3D model from.

As luck would have it, after I had made several rotations on the 35mm frames, we had a project that required the use of the 16mm camera in the microfilm plotter.  The University of Iowa had launched it's own satellite, Hawkeye I, and a film was made from it's perspective of it's orbit around the Earth.  Since they had to develop the entire roll at a time, they happened to have extra frames available on the roll.  So I made a quick change to the program and was able to make a movie of the calculator rotating in space.  It was very crude.  Imagine a calculator on an invisible turntable and after every revolution, the turntable would be tilted up more.  Unfortunately I no longer have that roll of film.  I still have a copy of the Hawkeye I movie that had a bug in the rendering, but my first 3D movie is lost.  I really wanted to make a movie that would show a program strip being fed through the magnetic card reader in the calculator.  But the 35mm camera had been restored to the microfilm plotter before I was able to modify the program.

Years later, I converted the original Fortran program to Applesoft Basic to draw on the Apple ][ hires screen.  Unfortunately at that time, I did not have the dataset for the calculator.

It's just recently1 I rediscovered the original microfilm.  I had stored in fiber drums a bunch of photographic material that I kept in my brother‑in‑law's basement, since I did not have a place of my own to store the stuff.  It was in storage much longer than expected, twenty‑five years!  So I call it Curt's Inadvertent Time Capsule.  This treasure trove contained the 35mm microfilm listings of the program that included the calculator dataset.  The only fly in the ointment was that the program used to create the microfilm backup had a bug that dropped a line of text whenever the frame was full and had to advance.  However, that's minor, I could usually figure out the missing line of code.  And since the dataset consisted mainly of rectangles to be drawn, I could synthesize the missing line.



E-mail curt@rostenbach.com