3D ROTATOR
by Richard Taylor
from Big K #8 (Nov'84)

RICHARD TAYLOR's PAGE
3D ROTATION: The Next Move

LAST MONTH's machine code allowed you to rotate the outline of a plane around
your TV screen in 3D. Problem is, though, you're stuck with the plane whether
you like it or not, and there's no particularly easy way to change it.
Fortunately, my endeavour to correct this dreadful misdemeanour is here in
the form of Listing 1. Simply tap it in and SAVE, making it auto-run from
line 10. If you don't have a Microdrive, then don't bother with the drive
SAVE and LOAD routines at lines 5500-5570 and 6500-6560 respectively. If you
don't have an Interface 1 connected then you'll find that the computer's a
bit cagey about accepting some of those lines anyway. Immediately after the
recording of Listing 1 make a copy of the machine code from last month's BIG K.

The program's a sort of 3D design/editor, allowing you to construct an
object, watch it build up on the screen, view it from various different
positions and at varying sizes. There are SAVE/LOAD options allowing you to
store an object on tape or Microdrive and return to it at a later date
(assuming it hasn't been accidentally wiped in the meantime).

After loading Listing 1 (it will automatically load the machine code) you're
greeted with, of all things, a black screen. At this point, you'd either LOAD
an object from tape/drive or start off from scratch by creating a new object.
The program's driven by single-key commands, as listed below. Simply press
the appropriate key and the computer will do its stuff!

C - This one lets you change the current INK, PAPER and BORDER colours. Due
to the problem's created by the Spectrum's restrictive attribute system, it's
not possible to make objects in multiple INKs.

E - This is the End option. Press this and you'll get the "STOP statement"
report. If you inadvertently press this key then "GO TO 100" will set you
back on the right lines with no harm done.

Q - If you've got a ZX Printer then this should give you a screen COPY.

S - This one lets you save your masterpiece to either tape (with the option
of verifying) or to one of the 8 possible Microdrives (have you ever seen a
Spectrum with 8 drives, 'cos I ain't!?).

L - Lets you LOAD an object back in from tape/drive, "binning" any object you
were working on at the time.

M - Allows you to enlarge or diminish an object. After choosing which of the
two possible options you require, you're asked for a magnification or
diminishing factor. If you squash an object too much then you'll find that
even when you re-magnify it to its former size it might look slightly
different due to small rounding errors when it was a little 'un. Going to the
other extreme, you'll find that your Spectrum won't be able to fit the whole
object on screen at one time. Getting a bit upset about this state of affairs
it will refuse to draw any lines that don't completely fit on the screen,
with some rather odd-looking results.

Keys: X, Y and Z - As with last month's demo prog, these keys allow you to
rotate the object in the appropriate axis.

Digit keys 1 to 9 - Again, in common with last month's prog, these keys
define how much the object rotates when you press one of the rotation keys.

The final three commands are associated with actually entering the data
needed to construct an object. As I mentioned last month, 3D points are
represented using x, y and z coordinates. The program uses the method of
defining 3D objects as points joined (or not, as the case may be) by lines.
Imagine that you had in your possession a piece of very rare and expensive 3D
graph paper. Given the coordinates of a point on the paper, then you could
place the tip of the pen in the appropriate position. Given another point you
could draw a straight line from the first to the second, or you could simply
leave it blank. You could then continue in the same manner through a third
and fourth point, etc.

There's only one problem with this method - it isn't possible to draw curves.
This is no great handicap, however, since in most applications you don't need
to draw curves anyway and, when these are required, you can often form
approximations of curves using several straight lines. The commands to
construct objects are as follows:

T - If you press this then the computer will ask for the x, y and z
coordinates of the next point. The computer will then move its imaginary pen
from its old position to the one specified, drawing a line as it goes.

P - Much as the 'T' command, except that the machine doesn't bother to
actually draw in the line between the old and new points.

D - Press this and the last line or jump ('P' line) that you entered is
instantly scrapped. (If it's a line, then you'll actually see it disappear
from the screen representation of the object.)

There are many different ways of entering the data for an object into a
program such as this. Some are easy for computers, others are easier for us
humans. The method I've used is relatively simple for computers, but it's not
the easiest of methods for us. However, since the object actually builds up
on the screen as you enter the data for it, it's not hard to spot mistakes
and quickly erase them using the 'D' command before they become too much of a
problem.

Now to some real objects. The first simple example of an object is a plain
old 2D square as shown in fig.1. It has four points on it, so you need to
enter five sets of data. "FIVE", I hear you exclaim, "Why five?" The answer
is that to make objects rotate properly the origin must lie directly in an
object's centre. The first set of coordinates simply allows you to move the
pen from its resting position at the origin to the first point on the object.
Even if you use 'T' for the first entry, the computer doesn't draw a line
from the origin since it knows that the first set of coordinates are simply
there to get the pen in the correct starting position.

You've probably noticed that the four points on the square have been marked
A, B, C and D. To be certain that the pen visits every point composing an
object and draws all the necessary lines it's a good idea to draw a picture
of your object and work out your route beforehand, labelling the points
you're going to "visit" as you go. It's also useful to write down beside each
point its coordinates, thus making the transferring of the object into the
computer a simple matter of typing in the coordinates in the right order. The
data for the square is given below. Simply type the preceding letter followed
by the three coordinates in response to the computer's prompts.

P,-40,  0, 40 : T, 40,  0, 40 :
T, 40,  0,-40 : T,-40,  0,-40 :
T,-40,  0, 40

You can rotate the object even if it is an uncompleted state and therefore
watch new lines being added from any vantage point you like.

The next example, shown in fig.2, is a cube. To make matters complicated
there are 12 lines to contend with but only 8 points. Unlike the square, it's
not possible to draw it without going over a line twice. The data for the
cube is as follows. Read across the page:

P, 40,-40,-40 : T,-40,-40,-40 :
T,-40, 40,-40 : T, 40, 40,-40 :
T, 40,-40,-40 : T, 40,-40, 40 :
T,-40,-40, 40 : T,-40, 40, 40 :
T, 40, 40, 40 : T, 40,-40, 40 :
P,-40,-40,-40 : T,-40,-40, 40 :
P,-40, 40,-40 : T,-40, 40, 40 :
P, 40, 40,-40 : T, 40, 40, 40

The method I've used to draw it is to construct two squares parallel to one
another, with one line joining them, and then go back with the 'P' command
and draw in the neglected three lines. I'm sure that this method isn't the
quickest and most efficient way. Perhaps you would like to calculate the
least number of moves you'd need to draw a cube.

Notice how both the objects are about 80 units in size - in height, width and
depth. These are about the largest dimensions that will allow an object to
fit comfortably onto the TV screen from all possible vantage points. If you
find that you've defined an object a shade too large, then you can always
squash it a bit with the 'M' command. There are definite maximum limits on
the size of coordinates: 127 and 128 respectively.

The next object is a sort of crystal,, two pyramids (one inverted) on top of
each other. The crystal is shown in fig.3 and the data is given below:

P,-30,  0,-30 : T, 30,  0,-30 :
T, 30,  0, 30 : T,-30,  0, 30 :
T,-30,  0,-30 : T,  0, 50,  0 :
T, 30,  0, 30 : T,  0,-50,  0 :
T,-30,  0,-30 : P, 30,  0,-30 :
T,  0, 50,  0 : T,-30,  0, 30 :
T,  0,-50,  0 : T, 30,  0,-30

This object has a much better "flow" to it than the cube, allowing you to
draw it completely only using one 'P' command. Notice how, in certain
orientations, the object looks rather strange. This effect is a result of the
lack of hidden line suppression when drawing the object. As well as leading
to a lack of solidity in the representation, it gives rise to arbitrary
situations where it's impossible for the brain to work out whether one line
is closer than another, with some weird results. Of course, there are ways
and means of preventing hidden lines being drawn, but the methods are very
mathematically involved and therefore painfully slow (even in machine code)
on small micros such as the Spectrum. So, unless you've got access to a
mainframe. I'm afraid that hidden lines are here to stay. Thankfully there
are a few "cheat" methods - that rely solely on particular properties of an
object to suppress hidden lines - that can usefully be employed.

The last 3D object example is a sort of '+' sign. It is the most complex of
the objects - there are 28 lines. Notice how this object rotates a little
more slowly than the others due to its greater complexity.

DATA FOR '+':

P,  5, -5,-10 : T, 40, -5,-10 : T, 40,  5,-10 : T,  5,  5,-10 :
T,  5,  5, 10 : T, 40,  5, 10 : T, 40, -5, 10 : T,  5, -5, 10 :
P, 40,  5, 10 : T, 40,  5,-10 : P, 40, -5, 10 : T, 40, -5,-10 :
P,  5,  5,-10 : T,  5, 40,-10 : T, -5, 40,-10 : T, -5,  5,-10 :
T, -5,  5, 10 : T, -5, 40, 10 : T,  5, 40, 10 : T,  5,  5, 10 :
P, -5, 40, 10 : T, -5, 40,-10 : P,  5, 40, 10 : T,  5, 40,-10 :
P, -5,  5,-10 : T,-40,  5,-10 : T,-40, -5,-10 : T, -5, -5,-10 :
T, -5, -5, 10 : T,-40, -5, 10 : T,-40,  5, 10 : T, -5,  5, 10 :
P,-40, -5, 10 : T,-40, -5,-10 : P,-40,  5, 10 : T,-40,  5,-10 :
P, -5, -5,-10 : T, -5,-40,-10 : T,  5,-40,-10 : T,  5, -5,-10 :
T,  5, -5, 10 : T,  5,-40, 10 : T, -5,-40, 10 : T, -5, -5, 10 :
P,  5,-40, 10 : T,  5,-40,-10 : P, -5,-40, 10 : T, -5,-40,-10