|★ CODING ★ LISTINGS ★ 3D ANIMATED GRAPHICS|COMPUTING WITH THE AMSTRAD) ★|
|3D Animated Graphics (Computing With the Amstrad)||Coding Listings|
IAN SHARPE presents some impressive animated 3D graphics
IF you saw June's 10 Liners page, you'll have seen a clever graphics routine by John Carpenter. It draws an almost-solid rippled surface, and as well as being remarkably short it operates quite quickly.
Great minds obviously think alike because it came into the office at the same tinre as a similar program submitted to ST User, our sister magazine edited by Roland Waddilove for Atari ST owners. The ST version, however, used a bit of machine code to produce an animated display, and just to prove the CPC has lots of life in it yet I set out to produce an Amstrad versionrProgram I is the result.
It is based on John's routine with a few modifications. Instead of drawing a single picture, my version draws eight - one after another. Each is a slightly different shape and once drawn it is stored in a safe place in memory.
When the eight frames are complete - it takes just over an hour - they are saved to tape or disc so you don't have to sit through the drawing process every time you run the program. The saved frames amount to 32k of data, so I suggest tape users insert a SPEED WRITE 1 command as line 5. There's a menu option to reload the frames when you next run the program.
When that's been done, select the Animate option. You will now see the eight frames played back in sequence to give a moving display. When the frames have been played, they are run backwards to give the impression of more frames than there actually are.
The effect is quite impressive, especially if you don't know how it's done. I found that playing only one sequence of frames ran too quickly, so four sequences are played simultaneously.
How it's done
The limit of eight frames is due to the amount of memory available. CPC6128 and ram pack owners with some knowledge of machine code could write a version with two to three times this number.
It's interesting to see how this complex picture is created by such a small program. The thing that caught my attention is that the display is drawn from the front towards the back, yet it manages to eliminate areas hidden by the foreground.
Each pixel in the drawing area is accessed by means of a nested loop. As you can see when the program runs, it works in columns and from bottom to top. The ripple effect is based on a sine wave rotated about an axis to give a surface. Perhaps the best way to explain it is like this: Imagine you aren't seeing the surface from the side but from directly above so that it looks like concentric circles.
As I said, each pixel is accessed in turn. For each one, the program uses Pythagoras's Theorum to calculate its distance from the centre of the ripple. If you're a bit rusty on maths, this is the one where you calculate the long side of a right angled triangle by taking the square root of the sums of the squares of the other two sides.
Having obtained the distance from the centre, it is fed into the equation z = sin(distance). z is the vertical height of the ripple coming out of the screen directly towards you. Now if you imagine the circles tilting away from you to form the actual screen display they become ovals.
This is achieved by multiplying the y value by a scale factor such as 0.8. To this new y value is added the vertical height just calculated. This final figure is the y ordinate plotted on the screen, x not having changed during the manipulation. But what about the hidden line removal?
Simple! During the plot of each column of pixels the program keeps a record of the maximum screen height reached so far. If a new point dips below this value it is hidden and therefore not plotted.
As the picture is symmetrical only the left hand side is calculated and the same values are used to form the right side.
The height and distance between waves depends on the number of the frame being plotted. The first one is virtually flat while the eighth is quite pronounced.
This method of hidden line removal has the disadvantage of eliminating low points which would be seen below higher areas in the foreground.
If you are prepared to sacrifice some speed you could test the screen with the TEST command to see if it is not the background colour before deciding not to plot the point. By using Mode 0 instead of Mode 1 you could regain some of the time lost and make these low points a darker shade than higher areas.
Once I'd seen how impressive the results are I added another type based on Lissajou figures to produce a snaking line of beads. I'm sure you can come up with ideas of your own to replace the existing routines. Don't try adding extra types without erasing the existing ones, because the program is rather a tight fit in memory.
If when debugging your typing and saving the program you get a Memory full error, type CLEAR, and try again.