Prev: 08980 Up: Map Next: 09090
08992: THE 'CIRCLE' COMMAND ROUTINE
The address of this routine is found in the parameter table.
This routine draws an approximation to the circle with centre co-ordinates X and Y and radius Z. These numbers are rounded to the nearest integer before use. Thus Z must be less than 87.5, even when (X,Y) is in the centre of the screen. The method used is to draw a series of arcs approximated by straight lines.
CIRCLE has four parts:
  • i. Tests the radius. If its modulus is less than 1, just plot X,Y.
  • ii. Calls CD_PRMS1, which is used to set the initial parameters for both CIRCLE and DRAW.
  • iii. Sets up the remaining parameters for CIRCLE, including the initial displacement for the first 'arc' (a straight line in fact).
  • iv. Jumps to DRW_STEPS to use the arc-drawing loop.
Parts i. to iii. will now be explained in turn.
i. The radius, say Z', is obtained from the calculator stack. Its modulus Z is formed and used from now on. If Z is less than 1, it is deleted from the stack and the point X,Y is plotted by a jump to PLOT.
CIRCLE 08992 RST 24 Get the present character.
08993 CP "," Test for comma.
08995 JP NZ,REPORT_C If not so, report the error.
08998 RST 32 Get next character (the radius).
08999 CALL CLASS_06 Radius to calculator stack.
09002 CALL CHECK_END Move to consider next statement if checking syntax.
09005 RST 40 Use calculator.
09006 DEFB 42 abs: X, Y, Z
09007 DEFB 61 re_stack: Z is re-stacked; its exponent is therefore available.
09008 DEFB 56 end_calc
09009 LD A,(HL) Get exponent of radius.
09010 CP 129 Test whether radius less than 1.
09012 JR NC,C_R_GRE_1 If not, jump.
09014 RST 40 If less, delete it from the stack.
09015 DEFB 2 delete: X, Y
09016 DEFB 56 end_calc
09017 JR PLOT Just plot the point X, Y.
ii. 2π is stored in mem-5 and CD_PRMS1 is called. This subroutine stores in the B register the number of arcs required for the circle, viz. A=4*INT (π*SQR Z/4)+4, hence 4, 8, 12, etc., up to a maximum of 32. It also stores in mem-0 to mem-4 the quantities 2π/A, SIN(π/A), 0, COS (2π/A) and SIN (2π/A).
C_R_GRE_1 09019 RST 40
09020 DEFB 163 stk_pi_2: X, Y, Z, π/2
09021 DEFB 56 end_calc
09022 LD (HL),131 Now increase exponent to 131, changing π/2 into 2π.
09024 RST 40 X, Y, Z, 2π.
09025 DEFB 197 st_mem_5: (2π is copied to mem-5)
09026 DEFB 2 delete: X, Y, Z
09027 DEFB 56 end_calc
09028 CALL CD_PRMS1 Set the initial parameters.
iii. A test is made to see whether the initial 'arc' length is less than 1. If it is, a jump is made simply to plot X, Y. Otherwise, the parameters are set: X+Z and X-Z*SIN (π/A) are stacked twice as start and end point, and copied to COORDS as well; zero and 2*Z*SIN (π/A) are stored in mem-1 and mem-2 as initial increments, giving as first 'arc' the vertical straight line joining X+Z, y-Z*SIN (π/A) and X+Z, Y+Z*SIN (π/A). The arc-drawing loop at DRW_STEPS will ensure that all subsequent points remain on the same circle as these two points, with incremental angle 2π/A. But it is clear that these 2 points in fact subtend this angle at the point X+Z*(1-COS (π/A)), Y not at X, Y. Hence the end points of each arc of the circle are displaced right by an amount 2*(1-COS (π/A)), which is less than half a pixel, and rounds to one pixel at most.
09031 PUSH BC Save the arc-count in B.
09032 RST 40 X, Y, Z
09033 DEFB 49 duplicate: X, Y, Z, Z
09034 DEFB 225 get_mem_1: X, Y, Z, Z, SIN (π/A)
09035 DEFB 4 multiply: X, Y, Z, Z*SIN (π/A)
09036 DEFB 56 end_calc
09037 LD A,(HL) Z*SIN (π/A) is half the initial 'arc' length; it is tested to see whether it is less than 0.5.
09038 CP 128
09040 JR NC,C_ARC_GE1 If not, the jump is made.
09042 RST 40
09043 DEFB 2 delete: X, Y, Z
09044 DEFB 2 delete: X, Y
09045 DEFB 56 end_calc
09046 POP BC Clear the machine stack.
09047 JP PLOT Jump to plot X, Y.
C_ARC_GE1 09050 RST 40 X, Y, Z, Z*SIN (π/A)
09051 DEFB 194 st_mem_2: (Z*SIN (π/A) to mem-2 for now)
09052 DEFB 1 exchange: X, Y, Z*SIN (π/A), Z
09053 DEFB 192 st_mem_0: X, Y, Z*SIN (π/A), Z (Z is copied to mem-0)
09054 DEFB 2 delete: X, Y, Z*SIN (π/A)
09055 DEFB 3 subtract: X, Y-Z*SIN (π/A)
09056 DEFB 1 exchange: Y-Z*SIN (π/A), X
09057 DEFB 224 get_mem_0: Y-Z*SIN (π/A), X, Z
09058 DEFB 15 addition: Y-Z*SIN (π/A), X+Z
09059 DEFB 192 st_mem_0: (X+Z is copied to mem-0)
09060 DEFB 1 exchange: X+Z, Y-Z*SIN (π/A)
09061 DEFB 49 duplicate: X+Z, Y-Z*SIN (π/A), Y-Z*SIN (π/A)
09062 DEFB 224 get_mem_0: sa, sb, sb, sa
09063 DEFB 1 exchange: sa, sb, sa, sb
09064 DEFB 49 duplicate: sa, sb, sa, sb, sb
09065 DEFB 224 get_mem_0: sa, sb, sa, sb, sb, sa
09066 DEFB 160 stk_zero: sa, sb, sa, sb, sb, sa, 0
09067 DEFB 193 st_mem_1: (mem-1 is set to zero)
09068 DEFB 2 delete: sa, sb, sa, sb, sb, sa
09069 DEFB 56 end_calc
(Here sa denotes X+Z and sb denotes Y-Z*SIN (π/A).)
09070 INC (IY+98) Incrementing the exponent byte of mem-2 sets mem-2 to 2*Z*SIN(π/A).
09073 CALL FIND_INT1 The last value X+Z is moved from the stack to A and copied to L.
09076 LD L,A
09077 PUSH HL It is saved in HL.
09078 CALL FIND_INT1 Y-Z*SIN (π/A) goes from the stack to A and is copied to H. HL now holds the initial point.
09081 POP HL
09082 LD H,A
09083 LD (23677),HL It is copied to COORDS.
09086 POP BC The arc-count is restored.
09087 JP DRW_STEPS The jump is made to DRW_STEPS.
(The stack now holds X+Z, Y-Z*SIN (π/A), Y-Z*SIN (π/A), X+Z.)
Prev: 08980 Up: Map Next: 09090