Let me tell you the whole story : I first programmed my perspective transform in FORTH for a 80386 PC with a VGA (640x480) graphic card. I join here my initial code :
- 3Danim86.zip
- 3D animations on a VGA display
- (9.89 KiB) Downloaded 183 times
My first goal was to plot a single true perspective view of a 3D wire frame not using floating point nor trigonometric functions but only integer operations because it was FORTH. I found my formula with 3D scalar and vector products of 3D vectors with only 16 bits integer components in 1986.
You will find this in files TDV.FTH and TDM.FTH
After that, instead of a single view I wanted to animate a rotation of the plotted object or of the point of view around the object.
You will find this in file TDA.FTH
The interface with the user for this animation used the keyboard keys ;
X for rotating around the Xaxis
Y for rotatiing around the Yaxis
Z for rotating around the Zaxis
N for a nearer point of view
V for a farther point of view
S for slower animation
F for faster animation
H for halting the animation
When repeating the X or Y or Z keys, it would change the rotaion to the opposite
When repeating the H key, it would do it step by step.
After that I wanted to do the plotting (already coded in 8086 assembler) faster than with calls to the BIOS 10 int. so, coded this lower level part with direct access to the graphic memory of my VGA card.
You will find this in file TGV.FTH (10 times faster than through the INT 10 BIOS call)
All this code (except the algorithms that I used) is nowaday obsolete, but constitute a good exemple of structured FORTH + FORTH-like macro assembler (for the 8086 etc. machines).
Afterward, I tranlated it for the 68008 ComputerOne FORTH on the QL.
By the way, here is my formula to step the plots for animating them by rotation of the object or the point of view, using the same vector operations that could be coded in FORTH (16 bits F83 model).
Calling the former point of vue vector V and the next one V', and given a rotational vector R :
V' = V + V ^ R
is a first order approximation (only valid if |R|<< |V| )
V' = V + ( V + ( ( ( V ^ R ) ^ R ) / 2 ) ) ^ R
is a much better second order approximation.
With this formula, when |V| the modulus of V is in the range of 16 bits and |R| the modulus of R in the range of 8 bits, the approximation error is generally of the order of 1 or 2 bits.
For instance, for rotating my avion around the Zaxis, I used |V| = 9000 and |R| = 200 and got only usual rounding errors for 16 bits integer operations.
Rotating around X : R = { 200 , 0 , 0 } - Rotating around Y : R = { 0 , 200 , 0 } - Rotating around Z : R = { 0 , 0 , 200 } - rotating around any vector : R = { xr , yr , zr }