To represent a 3-dimensional object on the screen a number of tricks can be used to fool the observer into interpreting the flat image as a 3--dimensional view. Luckily, because the brain is very good at extracting 3--dimensional information from a flat picture, only a few simple depth cues are required to create the illusion of the third dimension.
These simple techniques are very easy to program, and simple programs can produce excellent results. For more general 3-D views and truly lifelike effects much more complicated techniques and considerable computing power are needed.
The choice of colours for different parts of an object can help give an impression of depth. Cold or dark colours tend to appear to be further away than warm bright colours. This is especially marked on the BBC machine with the colour dark blue, which gives the impression of great distance.
Here is a program that uses different colours to give the illusion of depth. The object drawn is a hoop composed of a spiral looping around a circle which gives a similar shape to the popular mints of the same name. To draw the hoop we trace around a small circle as its centre moves round the hoop. The impression of depth is obtained by squashing the small circle in the y-direction, and colouring the most distant half of each loop dark-blue.
POLO
0 REM Polo
20 MODE1
30 VDU19,2,4;0;
40 VDU29,640;512;
50 VDU5
60 R%=40
70 MOVE 12*R%,0
80 FORA=0 TO 2*PI STEP 0.01
90 T=A*50
100 S=SIN(T)
110 IF S>0 THEN GCOL 3,2 ELSE GCOL 0,RND(2)*2-1
120 DRAW R%*(10*COS(A)+2*COS(T)),R%*(10*SIN(A)+S)
130 NEXT
140 GOTO80
Description of program
20 Select a 4-colour mode. 30 Change the palette so that logical colour 2 appears as dark blue. 40 Put the origin in the centre of the screen. 60 R% affects the size of the circles. 70 Move to the first point. 80 Step around the large circle. 90 Save A*50 as T to give a marginal increase in speed. 100 This avoids calculating SIN(T) more than once each time around the loop. 110 Select the colour and plotting action. The action EOR ensures that the blue lines will always appear behind the red and white line. RND(2)*2--l selects either red or white. 120 Draw a line to the next point around the spiral. COS(A) and SINUA) control the position in the large circle. COS(T) and S control the position in the small circles. 140 Start again.
One of the most obvious observations about a 3.imensional view is that you cannot see an object if it is behind something. While this is very simple to understand in a 3--dimensional world it causes many complications if we want to represent a [s-dimensional view on a flat screen.
To give the impression of depth distant objects must be obscured, or partly obscured, by the objects in the foreground. The main problems are how to tell which parts of a distant object are not visible and how to draw a partly-obscured object, which may be a very different shape from the original. The next program uses a very simple method to achieve the required effect.
Mountains
This program draws a view of randomly-generated snow-capped mountains as shown in the photograph above. The colours are chosen at random, and although this can produce some ridiculous effects, it can also produce colour schemes that are reminiscent of the subtle hues of an alpine landscape.
The largest most distant mountains are drawn first, and then 'closer' mountains are put on top of these obscuring them where they overlap. This technique for eliminating hidden lines, by drawing from the back and then over-plotting, is useful in many applications. Although at first sight it may seem to be rather slow and extravagant, the alternatives are considerably more complicated and probably not much faster. The method to use will obviously be governed by the nature of the object being drawn, but the 'pasting on top' approach, as used here, gives an easy solution for irregular objects.
The technique relies on the ability to fill in areas of colour rapidly. For line drawings a mask around the foreground object is filled in black (or whatever the background colour is) and then the object is drawn on top of the mask.
When the entire picture is complete the program will wait for any key to be pressed before starting again.
Each mountain is drawn as follows:
MOUNTS
0 REM Mountains
20 MODE1
30 VDU19,0,6;0;
40 VDU5
50 FOR MOUNTAIN%=900 TO 0 STEP -60
60 X_PEAK%=RND(1200)
70 Y_PEAK%=MOUNTAIN%+RND(50)
80 FOR SIDE%=0TO1
90 X_SLOPE%=RND(40)+20
100 Y_SLOPE%=RND(20)+30
110 MOVE X_PEAK%,Y_PEAK%
120 X%=X_PEAK%:Y%=Y_PEAK%
130 REPEAT
140 IF SIDE%=0 THEN X1%=X%+RND(X_SLOPE%) ELSE
X1%=X%-RND(X_SLOPE%)
150 Y1%=Y%-RND(Y_SLOPE%)
160 SNOW_LINE%=Y_PEAK%-Y1%/5-50:GCOL0,2
170 MOVEX1%,Y1%: PLOT85,X1%,0: MOVEX%,
0:PLOT85,X%,Y%
180 IF SNOW_LINE%<Y1% THEN GCOL0,3:MOVEX1%,Y1%:
PLOT85,X1%,SNOW_LINE%:MOVEX%,SNOW_LINE%:PLOT85,X%,Y%
190 X%=X1%:Y%=Y1%
200 GCOL0,1:DRAWX%,Y%
210 UNTIL POINT(X%,Y%)=-1
220 NEXT SIDE%
230 VDU19,RND(3),RND(8)-1;0;
240 NEXT MOUNTAIN%
250 A=GET:GOTO50
Description of program
30 Have a light-blue sky. 40 Remove the text cursor by linking the text and graphics cursor. 50 Each time around this loop a mountain is drawn. The y-coordinate of the peak is slightly above MOUNTAIN%. 60-70 Select a point for the peak. 80 Each time around this loop a single side of the mountain is drawn. 90-100 Select the slope of the mountain-side. 110 Move to the top of the mountain. ' 120 The point (X%,Y%) is the current position on the mountain-side. 130 In this loop we step down the slope until we run off the edge of the screen. 140-150 (Xl%,Yl%) is the next point down the mountain-side. 160 Calculate where the snow-line will be, and select the mountain colour. 170 Fill the region below the line between (X%,Y%) and (Xl%,Yl%). 180 If we are above the snow-line draw some snow. 190 Move (X%,Y%) one step down. 200 Draw a line along the mountain-side, so that it will stand out from more distant mountains. 210 Carry on until we run off the edge of the screen. 230 Change the colour scheme at random. 250 Wait for a key to be pressed then start again.
It is not too hard to write a generalised routine that will produce a perspective view of a ii-dimensional object. The routine could take a stored representation of the object and allow you to view it from any point.
This approach requires 3-dimensional information about the object to be stored in the program, and the stored representation is then acted on by the viewing routine to give the required perspective image which is projected onto a flat plane. The perspective view is rather like the shadow cast by the object.
For simple programs this method would be rather cumbersome and slow, and has many facilities that are not required to give just one view of the object.
A more straightforward method is to draw a single perspective view of the object directly on the screen, the illusion of depth being created by suitably distorting the shape of the flat object. Some of the techniques used to give the impression of ti-dimensional objects are illustrated below:
| ![]() | ||
| ![]() | ||
| ![]() | ||
| ![]() |
This program uses a procedure that draws a very simple perspective view of a cube to fill the screen with advancing cubes. The most distant cubes are drawn first and then obscured by the foreground cubes which are 'pasted on top'. The 3-13 effect is enhanced by drawing a large number of small cubes in the distance, drawing fewer in the foreground, and increasing the size of the cubes as they approach the observer.
CUBES
0 REM Cubes
20 MODE1
30 VDU5
40 VDU19,2,4;0;
50 REPEAT
60 FORY%=0 TO 1200 STEP 10
70 H%=1100-RND(Y%)
80 PROCCUBE(RND(1300)-50,H%,(1200-H%)
/6,RND(4)-1)
90 NEXT
100 VDU19,RND(3),RND(7);0;
110 UNTIL FALSE
120 DEFPROCCUBE(X%,Y%,S%,C%)
130 D%=S%/3:E%=S%+D%
140 VDU29,X%;Y%;
150 GCOL0,C%
160 MOVE0,0:MOVE0,S%:PLOT85,D%,E%
170 MOVE0,0:PLOT85,E%,E%
180 MOVE0,0:PLOT85,E%,D%
190 MOVE0,0:PLOT85,S%,0
200 GCOL0,C%+3
210 DRAWS%,S%:DRAW0,S%:DRAW0,0:DRAWS%,
0
220 MOVE0,S%
230 DRAWD%,E%:DRAWE%,E%
240 DRAWE%,D%:DRAWS%,0
250 MOVES%,S%:DRAWE%,E%
260 ENDPROC
Description of program
20 4-colour mode. 30 Link text and graphics cursors to get rid of the text cursor. 40 Make logical colour 2 appear as dark blue. 50 Each time around this loop the cubes advance to the front of the screen. 60 Move Y% down the screen. 70 Make H% the Y% coordinate at which a cube is drawn. Calculating H% like this ensures that fewer cubes are drawn in the foreground. 80 Draw a cube with random colour and x-coordinate. The size grows as the y-coordinate decreases. 100 Change the palette at random. 120 PROCCUBE(X%,Y%,S%,C%) draws a cube of size S% in logical colour C% at the point X%,Y%. 130 E% and D% are used to draw the far side of the cube. 160-190 Fill in the cube. 210-250 Draw the edges of cube.
The following program draws a 3-dimensional view of a sphere. The sphere is represented by a series of flat circular discs. The program reads in the following values:
ST% controls the step size around the loop that draws each disc, and how many discs are drawn. Good results are obtained when ST% is 50.
S% is the radius of the sphere. To fill the screen make 8% about 500.
C1% and C2% specify the colours of the centre and edge of the discs. They must be in the range 0 to 3.
SPHERE
0 REM Sphere
20 MODE1
30 VDU29,640;512;
40 DIM C(300)
50 INPUT"Step size ? "ST%
60 INPUT"Size ?"S%
70 INPUT"Central colour ? "C1%
80 INPUT"Edge colour ? "C2%
90 CLS
100 VDU23;10,32,0;0;0;
110 I%=-2
120 FORA=0TO 2*PI+PI/ST% STEP PI/ST%
130 I%=I%+2
140 C(I%)=S%*COS(A)
150 C(I%+1)=S%*SIN(A)
160 NEXT
170 FORFI=-PI/2 TO PI/2 STEP PI/ST%
180 VDU29,600;500+S%*0.8*SIN(FI);
190 MOVE0,0
200 CS=COS(FI)
210 F=CS*SIN(PI/ST%)
220 GCOL0,C1%
230 FORJ%=0 TO I% STEP 2
240 X%=CS*C(J%):Y%=F*C(J%+1)
250 MOVE0,4:PLOT85,X%,Y%
260 NEXT
270 GCOL0,C2%
280 MOVE CS*C(0),F*CS*C(1)
290 FORJ%=2 TO I% STEP 2
300 DRAW CS*C(J%),F*C(J%+1)
310 NEXT J%,FI
320 GOTO50
Description of program
20 4-colour mode. 30 Move the origin to the centre of the screen. 40 The array C will hold the coordinates of points around the edge of each disc that is drawn . 50-80 Read in values for the step size around each loop, the size of the sphere, and the logical colour numbers of the centre and edge of each disc. 100 Remove the text cursor. 110 I% is used to index the array C(200). 120-160 In this loop we store all the coordinates the points around the edge of the largest disc. 170 Draw a disc each time around this loop. 180 Move the origin to the centre of the disc to be drawn. 200-210 CS and F are used to reduce the size of the x- and y-coordinates of the stored disc, so that the discs give the outline of a sphere. 220 Select the colour of the centre of the disc. 230-260 Draw the centre of the disc. 270 Select the colour of the line around the edge of the disc. 280-310 Draw the line around the edge of the disc. 320 Go back and start again.
One of the limitations of the graphics on the BBC microcomputer is that there is no control over the brightness and intensity of the colours, making it hard to produce the shading effects that are required to represent lifelike 3-dimensional objects.
This program gets round this problem by using a random distribution of coloured dots to give the impression of different colour intensities.
The intensity of colour in a region depends on the number of pixels that are set - for maximum brightness all the pixels will be on, the dimmest effect is achieved when all the pixels are off, and there is a range of values between these extremes. For each pixel in the region we choose a random number between I and a maximum value (for example 100 to give 100 different shades). If the random number chosen is less than the region's intensity number then we set that pixel; otherwise it is black.
The limitation of this method is that it is rather slow since the random function is called for every dot in the region. It could be speeded up by using a pseudo-random number obtained by incrementing a randomly-chosen pointer into part of the ROM.
PLANET1
0 REM Planets
20 MODE1
30 VDU5
40 REPEAT
50 VDU29,RND(1000)+100;RND(800)+100;
60 LC%=RND(3)
70 SIZE%=RND(150)
80 SIZES%=SIZE%*SIZE%
90 FORY%=-SIZE%TOSIZE%STEP4
100 X%=SQR(SIZES%-Y%*Y%)
110 X2%=2*X%
120 FORI%=-X%TOX%STEP4
130 IF RND(X2%)-X%<I% THEN GCOL0,LC% E
LSE GCOL 0,0
140 PLOT69,I%,Y%
150 NEXT I%,Y%
160 VDU19,LC%,RND(7);0;
170 UNTIL FALSE
Description of program
20 4-colour mode. 30 Remove text cursor. 40 Draw a planet each time round this loop. 50 The centre of the planet will be at the origin, defined to be at a random position not too close to the edge of the screen. 60 LC% is the logical colour in which the planet is drawn. 70 SIZE% is the radius of the planet. 90 The planet is drawn with lines of dots. In MODE 1 each dot is a 4x4 square, hence STEP 4. 100 The point (X%,Y%) is the end of the current line of dots. 120 This loop draws a line of dots. 130 This determines whether a dot is light or dark. For each dot a random number is picked and compared with the position of that dot. This ensures that there is 100% chance of a dot being bright on the far right-hand side and 0% on the left, with a smooth range of intermediate values across the planet. 140 Draw a dot at the point (I%,Y%). 160 Change the palette so that any of 7 colours can appear.
The disadvantage of the previous program is that it runs very slowly. The following program produces a similar effect but is much faster - it also demonstrates how to define your own characters.
PLANET2
0 REM Character Defined Planets
20 MODE1:VDU5
30 FORF=0TO1:CLG:GCOL0,3
40 VDU29,500;500;:C%=2
50 SIZ%=C%*32:SIZS%=SIZ%*SIZ%
60 FORY%=-SIZ%TOSIZ%STEP4
70 X%=SQR(SIZS%-Y%*Y%)
80 X2%=2*X%
90 FORI%=-X%TOX%STEP4
100 R%=RND(X2%):IFF=0THEN R%=0
110 IFR%<I%+X%THEN PLOT 69,I%,Y%
120 NEXT,
130 PROCCH(504-SIZ%,500+SIZ%,SIZ%*2,SI
Z%*2,224+15*F)
140 NEXT
150 REPEAT
160 VDU29,RND(1000);RND(1000);
170 FORI=0TO1
180 IF I=0 THEN R%=225:GCOL0,0 ELSE R%
=240:GCOL0,RND(3):VDU19,RND(3),RND(7);0;
190 FORJ%=0TO 32-SIZ%*2STEP-32
200 FOR I%=0TOSIZ%*2-32STEP 32
210 MOVEI%,J%:VDUR%:R%=R%+1:NEXT,:NEXT
220 UNTIL0
Description of program
30 The first time around this loop we draw a solid cirle, then a shaded planet; both are saved as a sequence of characters. 60 STEP 4 determines the number of characters needed to save the planet. Valid values are in the range 1 to 4. Draw the planet or background mask. 130 Call PROCCH to define characters to represent the shape we have just drawn. 150 We now run all over the screen dumping characters. 170-180 First draw a back mask, and then the planet on top of this in a random colour. 190-210 Put the characters defined in PROCCH in their original positions.
PROCCH
This routine takes a region of the screen and defines characters to reproduce the pattern in that region. The routine will only work in modes in which the pixels are 4x4. The region to be turned into characters is specified as shown below:
The parameters X% and Y% must be multiples of 32 so that the region is exactly covered wi th whole characters. The parameter ST% is the code for the first character to be used. Memory is reserved for defining characters with codes 224 to 255, so when PROCCH is first called it would be sensible to supply the value 224 to ST%.
230 DEFPROCCH(OX%,OY%,X%,Y%,ST%)
240 DIM B%8
250 CN%=0
260 FOR J%=0TO 32-Y% STEP -32
270 FOR I%=0TOX%-32 STEP 32
280 VDU29,OX%+I%;OY%+J%;:C%=-1:CN%=CN%+1
290 FOR IY%=1TO-32STEP-4
300 V%=0:C%=C%+1
310 FOR IX%=1TO32STEP4
320 IF POINT(IX%,IY%)=3 THEN PIX%=1 ELSE PIX%=0
330 V%=V%*2+PIX%:NEXT
340 B%?C%=V%:NEXT
350 IF ST%+CN%=256:PRINT"TOO BIG":ENDPROC
360 VDU23,ST%+CN%,B%?1,B%?2,B%?3,B%?4,B%?5,B%?6,
B%?7,B%?8
370 MOVE0,-4:GCOL0,1:VDU(ST%+CN%)
380 NEXT,
390 ENDPROC
Description of PROCCH
240 The byte array B% will hold the eight values that specify the bit pattern of each row of the character being defined.
260-270 These loops move the point (I%,J%) to the top left-hand corner of each character that is defined. 280 Put the origin at the top left-hand corner of the current character. C% is used to index the array B%; it counts the rows of pixels within the character. Since we are about to define a new character we add one to CN%. 290 This loop moves the scan down one row. 300 V% will hold a number that describes the bit pattern on a row. 310 This loop scans across the 8 pixels which will form a row within the character. 320 If the pixel at the point (IX%,IY%) is white then make PIX%=l. 330 Alter V% so that it also describes;the last pixel. 340 Save the value of V% describing that row of pixels in the array B%. 350 Make sure that we are not going to try to define an illegal character. 360 Define the character number ST%+CN% using the bit patterns we have saved in B%. 370 Put the character just defined on top of the pattern it is derived from to make sure it is correct.