100 XC = 170: YC = 100: RC = 95 110 KEY OFF: KEY 6, "WIDTH 80" + CHR$(13) 120 PI = 3.1415926535# 500 GOSUB 5000 520 U0 = 0: V0 = 0: R0 = (1 - SIN(PI / N)) / (1 + SIN(PI / N)) 540 P = RF * R0: Q = 0 580 SCREEN 1: CLS 600 GOSUB 7000 630 RO = SIN(PI / N) / (1 + SIN(PI / N)): RR = 1 / (1 + SIN(PI / N)) 640 FOR I = 0 TO N - 1 650 U0 = RR * COS(AZ + 2 * I * PI / N): V0 = RR * SIN(AZ + 2 * I * PI / N) 660 CC = 3: GOSUB 8000 665 IF FC$ = "Y" THEN PAINT (CX, CY), 1, 3 670 NEXT I 2000 REM 2010 LOCATE 21, 1: PRINT "PRESS ANY" 2015 LOCATE 22, 1: PRINT "KEY TO" 2020 LOCATE 23, 1: PRINT "CONTINUE" 2030 U$ = INPUT$(1) 2040 LINE (0, 0)-(75, 200), 0, BF 2050 LOCATE 1, 1: PRINT "OPTIONS" 2060 LOCATE 3, 1: PRINT "1 - NEW" 2065 LOCATE 4, 1: PRINT "AZIMUTH" 2070 LOCATE 5, 1: PRINT "FOR CHAIN" 2080 LOCATE 7, 1: PRINT "2 - NEW" 2085 LOCATE 8, 1: PRINT "DIAGRAM" 2086 LOCATE 10, 1: PRINT "3 - HOW" 2087 LOCATE 11, 1: PRINT "IT WORKS" 2088 LOCATE 13, 1: PRINT "PRESS ANY" 2089 LOCATE 14, 1: PRINT "OTHER KEY" 2090 LOCATE 15, 1: PRINT "TO QUIT" 2091 LOCATE 17, 1: PRINT "SELECT" 2092 LOCATE 18, 1: PRINT "OPTION" 2140 U$ = INPUT$(1) 2150 IF U$ = "2" THEN 100 2155 IF U$ = "3" THEN GOSUB 6000 2160 IF U$ = "3" THEN 100 2170 IF U$ <> "1" THEN 2800 2200 REM NEW AZIMUTH 2210 LINE (0, 0)-(75, 200), 0, BF 2220 PAINT (CX, CY), 0, 2 2230 GOSUB 7000 2240 LOCATE 1, 1: PRINT "INPUT NEW" 2250 LOCATE 2, 1: PRINT "AZIMUTH" 2260 LOCATE 3, 1: PRINT "FOR FIRST" 2270 LOCATE 4, 1: PRINT "CIRCLE OF" 2280 LOCATE 5, 1: PRINT "CHAIN" 2290 LOCATE 7, 1: INPUT AZ$: AZ = VAL(AZ$) * PI / 180 2300 LINE (0, 0)-(75, 200), 0, BF 2320 GOTO 630 2390 END 2800 REM 2820 SCREEN 0: WIDTH 80: KEY ON 2890 END 5000 REM HELP SCREEN 5005 SCREEN 0: WIDTH 80: CLS 5010 COLOR 4: PRINT " STEINER CHAIN": PRINT 5020 COLOR 14: PRINT "CONSTRUCT TWO CIRCLES, ONE WITHIN THE OTHER, AND THEN DRAW A CHAIN" 5030 PRINT "OF CIRCLES IN THE SPACE BETWEEN. IN ALMOST EVERY CASE, THE CHAIN WILL NOT" 5040 PRINT "CLOSE EXACTLY. ONLY IN SPECIAL CASES WILL THE CHAIN CLOSE EXACTLY." 5050 PRINT : PRINT "IF THE CHAIN DOES CLOSE EXACTLY, IT IS A REMARKABLE FACT THAT IT WILL CLOSE" 5060 COLOR 3: PRINT "REGARDLESS OF WHERE THE FIRST CIRCLE IN THE CHAIN IS DRAWN" 5070 COLOR 14: PRINT : PRINT "SUCH A CHAIN IS CALLED A STEINER CHAIN" 5080 PRINT "THIS PROGRAM DEMONSTRATES STEINER CHAINS" 5110 COLOR 9: PRINT : PRINT "INPUT THE NUMBER OF CIRCLES (AT LEAST 3) IN THE CHAIN " 5120 COLOR 3: PRINT " (THIS VALUE DETERMINES THE RELATIVE DIAMETERS OF THE TWO CIRCLES:" 5130 PRINT " THE LARGER THE VALUE OF N, THE LARGER THE INNER CIRCLE)" 5140 COLOR 9: INPUT "INPUT THE NUMBER OF CIRCLES IN THE CHAIN "; N$ 5150 N = VAL(N$): IF N < 3 THEN N = 3 5210 COLOR 2: PRINT : PRINT "INPUT THE OFFSET OF THE TWO CIRCLES (0 TO 100)" 5220 COLOR 10: PRINT " (A VALUE OF ZERO MEANS CONCENTRIC CIRCLES," 5230 PRINT " A VALUE OF 100 MEANS THE CIRCLES TOUCH)" 5240 COLOR 2: INPUT "INPUT THE OFFSET VALUE "; RF$ 5250 RF = VAL(RF$) / 100: IF RF < 0 THEN RF = 0: IF RF >= 1 THEN RF = .99 5260 COLOR 5: PRINT : INPUT "INPUT THE AZIMUTH OF THE FIRST CIRCLE IN THE CHAIN "; AZ$ 5270 AZ = VAL(AZ$) * PI / 180 5280 COLOR 12: PRINT : INPUT "DO YOU WANT TO COLOR IN THE CIRCLES - Y/N "; FC$ 5290 IF FC$ = "y" THEN FC$ = "Y" 5380 COLOR 7: SCREEN 0: WIDTH 80: CLS 5390 RETURN 6000 REM SUB HOW.IT.WORKS 6005 SCREEN 0: WIDTH 80: CLS 6010 PRINT "HOW IT WORKS": PRINT 6015 PRINT "The trick here is finding those special pairs of circles that allow" 6020 PRINT "Steiner Chains. Devising a formula directly for the geometry of Steiner" 6025 PRINT "Chains is brutal. Using a technique called Inversion Geometry, the problem" 6030 PRINT "becomes rather simple": PRINT 6035 PRINT "Inversion geometry works like this. Pick a point (the inversion point)." 6040 PRINT "Call it I. Any other point at distance R from I is mapped to a new point" 6045 PRINT "with the same azimuth but distance 1/R. In inversion geometry:" 6050 PRINT " - If I is on a line, the line inverts onto itself" 6055 PRINT " - If I is not on a line, the line inverts into a circle" 6060 PRINT " - If I is on the circumference of a circle, the circle inverts into a line" 6065 PRINT " (We can see the last two relations in polar coordinates. The equation" 6070 PRINT " of line x=1 is r=sec a. The equation of a circle with diameter " 6075 PRINT " (0,0)-(1,0) is r=cos a.)" 6080 PRINT " - If I is not on the circumference of a circle, the circle inverts" 6085 PRINT " into another circle.": PRINT 6090 PRINT "Press any key to see next page": X$ = INPUT$(1) 6095 CLS 6100 PRINT "The fact that circles invert into circles is the key to the construction" 6105 PRINT : PRINT "We proceed like this:" 6110 PRINT " 1. Decide on the number of circles in the chain" 6115 PRINT " 2. Draw the outer bounding circle" 6120 PRINT " 3. Working IN INVERSE SPACE, calculate the radii for a chain of" 6125 PRINT " equal circles" 6130 PRINT " 4. Calculate the radius of the inner circle. It will be concentric" 6135 PRINT " with the outer circle. It takes nothing more than simple trig" 6140 PRINT " to do operations 1-4." 6145 PRINT " 5. Decide on the offset of the bounding circles in real space" 6150 PRINT " 6. Find the inversion point that maps the concentric circles in" 6155 PRINT " inverse space into the desired offset circles in real space." 6160 PRINT " 7. Calculate the locations of the bounding circles and the chain" 6165 PRINT " circles in inverse space" 6170 PRINT " 8. Invert the locations through the inversion point to find the" 6175 PRINT " coordinates in real space.": PRINT 6180 PRINT "Press any key to continue": X$ = INPUT$(1) 6195 RETURN 7000 REM DRAW MASTER CIRCLES 7010 U0 = 0: V0 = 0: RO = (1 - SIN(PI / N)) / (1 + SIN(PI / N)) 7020 R = SQR(P * P + Q * Q): SF = RC * (RO * RO - R * R) / RO 7030 DX = XC - P * SF / (RO * RO - R * R): DY = YC - Q * SF / (RO * RO - R * R) 7040 CC = 2: GOSUB 8000 7050 U0 = 0: V0 = 0: RO = 1: CC = 2: GOSUB 8000 7060 IF FC$ = "Y" THEN PAINT (CX, CY), 3, 2 7090 RETURN 8000 REM INVERT A CIRCLE 8005 REM ORIGINAL CIRCLE AT U0,V0, RADIUS RO 8010 REM INVERSION POINT AT P,Q 8015 REM INVERTED CIRCLE AT I0,J0, RADIUS RI 8020 REM COMPUTE DISTANCE U0,V0 - P,Q 8025 L = SQR((U0 - P) ^ 2 + (V0 - Q) ^ 2) 8030 IF L <> 0 THEN 8100 8040 REM INVERT CIRCLE CENTERED ON INVERSION POINT 8050 I0 = P: J0 = Q: RI = 1 / RO 8060 CX = I0 * SF + DX: CY = J1 * SF + DY: RAD = RI * SF 8070 GOSUB 9200 8080 GOTO 8390 8100 REM INVERT CIRCLE NOT CENTERED ON INVERSION POINT 8130 REM INVERT NEAR SIDE OF CIRCLE 8135 U1 = U0 + RO * (P - U0) / L: V1 = V0 + RO * (Q - V0) / L 8137 R = SQR((U1 - P) ^ 2 + (V1 - Q) ^ 2) 8140 I1 = P + ((U1 - P) / R) / R: J1 = Q + ((V1 - Q) / R) / R 8150 REM INVERT FAR SIDE OF CIRCLE 8155 U2 = U0 - RO * (P - U0) / L: V2 = V0 - RO * (Q - V0) / L 8157 R = SQR((U2 - P) ^ 2 + (V2 - Q) ^ 2) 8160 I2 = P + ((U2 - P) / R) / R: J2 = Q + ((V2 - Q) / R) / R 8170 REM PLOT INVERSE CIRCLE 8180 I0 = (I1 + I2) / 2: J0 = (J1 + J2) / 2: RI = SQR((I1 - I2) ^ 2 + (J1 - J2) ^ 2) / 2 8190 CX = I0 * SF + DX: CY = J0 * SF + DY: RAD = RI * SF 8200 GOSUB 9200 8390 RETURN 9000 REM 9010 U$ = INPUT$(1) 9020 SCREEN 0: WIDTH 80 9190 END 9200 REM DRAW CIRCLES 9205 IF RAD > .5 THEN 9230 9210 PSET (CX, CY), CC 9220 GOTO 9290 9230 X0 = RAD: Y0 = 0: FOR T = 0 TO .52 * PI STEP .02 * PI 9235 X1 = RAD * COS(T): Y1 = RAD * SIN(T) 9237 LINE (CX + X0, CY + Y0)-(CX + X1, CY + Y1), CC: LINE (CX - X0, CY + Y0)-(CX - X1, CY + Y1), CC 9240 LINE (CX + X0, CY - Y0)-(CX + X1, CY - Y1), CC: LINE (CX - X0, CY - Y0)-(CX - X1, CY - Y1), CC 9242 X0 = X1: Y0 = Y1: NEXT T 9290 RETURN 9900 REM END