SURFACE

The last program is the most sophisticated of the graphics programs in this chapter. It gives a perspective view of a three-dimensional surface viewed from any specified position, even vertically above the surface. The program gives the appearance of a surface tiled with squares, and removes lines lying behind the surface to give a more realistic plot. The hidden-line routine has wider application, and can be used to add hidden-line removal to any three dimensional graph.

The following examples show a peaked surface produced by the equation:

Z=COS(O/1.5)*EXP(-O/5)*5

where O is the radius from the centre of the surface. The program first prompts for the coordinates of the viewing position. The larger the coordinates are, the further the viewing position will be from the curve, and the smaller the resulting surface will be. The diagrams below are obtained with X=45, Y=25, and Z=15:

Surface with hidden line removal

The same curve plotted without hidden-line removal is shown below:

Surface without hidden line removal


BBC Computer Version

10 REM ...Surface...
20 DIM Q%(319),R%(319),O%(22),P%(22)

Choose view position, set upper and lower horizons to top and bottom of screen, and choose 320x256 graphics mode.

30 INPUT"View from: "'"X="L,"Y="M,"Z="N
40 S=L*L+M*M: R=SQR(S)
50 T=S+N*N: Q=SQR(T)
60 FOR I%=0 TO 319: R%(I%)=255: Q%(I%)=0: NEXT
70 E%=10: MODE4: VDU5

Scan plane, dividing it into squares.

80 FOR F%=-E% TO E%+1: FOR G%=-E% TO E%+1: U%=X%:
V%=Y%

Calculate O = distance from origin, and solve equation of surface in terms of O.

90 O=SQR(F%*F%+G%*G%)
100 X=-G%: Y=-F%: Z=COS(O/1.5)*EXP(-O/5)*5

Calculate O = distance of point from eye, and project point onto screen coordinates (X%,Y%).

110 O=(T-X*L-Y*M-Z*N)*R
120 IF O<.1 THEN 200
130 X%=400*(Y*L-X*M)*Q/O+160: IF X%<0 X%=0
140 Y%=500*(Z*S-N*(X*L+Y*M))/O+128
l70 IF G%=-E% Q%(X%)=Y%: R%(X%)=Y%

Draw 2 sides of square on surface, and store coordinates of previous row.

180 IF G%+E% A%=G% AND 1: PROCDRAW
190 IF F%+E% U%=O%(G%+E%): V%=P%(G%+E%): A%=F% AND 1:  PROCDRAW
200 O%(G%+E%)=X%: P%(G%+E%)=Y%
210 NEXT: NEXT
220 REPEAT UNTIL FALSE

PROCDRAW - Draw from U%,V% to X%,Y% with hidden-line removal. Note that lines must be drawn away from observer for hidden-line removal to work correctly.

230 DEF PROCDRAW M%=Y%-V%: NS=ABS(X%-U%): IF N%=0 ENDPROC
240 S%=(X%-U%)/N%
250 FOR I%=1 TO N%: J%=U%+I%*S%: K%=V%+I%*M%/N%

If above upper horizon or below lower horizon make new horizon.

270 IF K%>Q%(J%) Q%(J%)=K%
280 IF K%<R%(J%) R%(J%)=K%
290 IF A%=0 THEN 320
300 MOVE4*(J%-S%),4*(Q%(J%-S%)): DRAW4*J%,4*Q%(J%)
310 MOVE4*(J%-S%),4*(R%(J%-S%)): DRAW4*J%,4*R%(J%)
320 NEXT: ENDPROC
Variables:
A%	- Flag - whether to draw
E%	- Number of squares across surface
J%,K%	- Next point to be plotted by PROCDRAW
L,M,N	- Coordinates of view position
O%,P%	- Vectors holding coordinates  of previous row for connecting points across. 
	Dimension should be 2*E%+1
Q,R,S,T	- Constants for projection
US,V%   - Previous screen coordinates to be plotted
X%,Y%   - New screen coordinates to be plotted

Atom Version

10 REM ...SURFACE...
20 DIM Q255,R255,O22,P22

Choose view position, set upper an lower horizons to top and bottom of screen, and choose 256x192 graphics mode.

30 FINPUT"VIEW FROM:"'"X="%L,"Y="%M,"Z="%N
40 %S=%L*%L+%M*%M;%R=SQR%S
50 %T=%S+%N*%N; %Q=SQR%T
60 FOR I=0T0255; R?I=191; Q?I=0 NEXT
70 E=10; CLEAR4

Scan plane, dividing it into squares

80 FOR F=-E TO E+1; FOR G=-E TOE+1; U=X; V=Y

Calculate %O disstance from origin, and solve equation of surface in terms of %O

 90 %O=SQR(F*F+G*G)
100 %X=-G; %Y=-P; %Z=COS(%O/1.5)*EXP(-%O/5)*5

Calculate %O distance of point from eye, and project point onto screen coordinates (X,Y).

110 %O=(%T-%X*%L-%Y*%M-%Z*%N)*%R
120 FIF %O<0.1 GOTO m
130 X=%(400*(%Y*%L-%X*%M)*%Q/%O)+128; IF X<0 X=0
140 Y=%(500*(%Z*%S-%N*(%X*%L+%Y*%M))/%O)+96

Avoid plotting outside screen area.

180 IF Y<0 Y=0
190 IF Y>191 Y=191
200 IF G=-E Q?X=Y; R?X=Y

Draw 2 sides of square on surface, and store coordinates of previous row.

210 IF G+E A=G&1; GOSUB d
220 IF F+E U=O?(G+E); V=P?(G+E); A=F&1; GOSUB d
230mO?(G+E)=X; P?(G+E)=Y
240 NEXT; NEXT
250 PRINT $7; DO UNTIL 0

d - Draw from U,V to X,Y with hidden-line removal. Note that line must be drawn away from observer for hidden-line removal to work correctly.

400dM=Y-V; N=ABS(X-U); IF N=0 RETURN
410 S=(X-U)/N
500 FOR I=1 TO N; J=U+I*S; K=V+I*M/N
503 IFJ<0 OR J>255 GOTO e

If above upper horizon or below lower horizon make new horizon.

505 IF K>Q?J; Q?J=K
510 IF K<R?J; R?J=K
513 IF A=0 GOTO e
515 MOVE (J-S),(Q?(J-S)); DRAW J,(Q?J)
517 MOVE (J-S),(R?(J-S)); DRAW J,(R?J)
520eNEXT; RETURN

Variables:

A	- Flag - whether to draw
E	- Number of squares across surface
J,K	- Next point to be plotted by PROCDRAW
$L,%M,%N - Coordinates of view position
O,P	- Vectors holding coordinates of previous row for connecting points across. 
	Dimension should be 2*E+1
$Q,%R,%S,%T - Constants for projection
U,V	- Previous screen coordinates to be plotted
X,Y	- New screen coordinates to be plotted

Further Suggestions

Other pleasing plots can be obtained by altering the function in line 100 of the programs. Interesting functions are:

Function:			Shape:
Z=(SIN(X*X/16)+SIN(Y*Y/16))	Rippled surface
Z=.05*(X*X-Y*Y)			Saddle curve

A sample plot of the 'saddle curve' is shown below:

Saddle curve

The effect of hidden-line removal can be illustrated by replacing the routine PROCDRAW in the BBC Version by:

230 DEF PROCDRAW MOVE U%,V%: DRAW X%,Y%: ENDPROC

Alternatively, in the Atom version, replace routine d by:

400dMOVE U,V; DRAW X,Y; RETURN

The changes suggested above get rid of all hidden curves, showing the complete 'wire-frame' mesh.

Surface shown as wire frame mesh

To get the second diagram on this page, change these lines:

505 Q?J=K
510 R?J=K

This is what the rippled surface looks like:

Rippled surface, from 40,30,25