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:
The same curve plotted without hidden-line removal is shown below:
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: ENDPROCVariables: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 correctl
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:
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.
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: