DECLARE SUB DRAW.CIRCLE (CX!, CY!, RAD!, CC!) CONST PI = 3.141593 XC = 160: YC = 100: RC = 95 SCREEN 1 LINE (40, 1)-(270, 85), 3, B LINE (40, 1)-(50, 10) LINE (270, 1)-(260, 10) LINE (155, 50)-(50, 10) LINE (155, 50)-(260, 10) LINE (40, 80)-(120, 38) LINE (270, 80)-(190, 38) LINE (40, 95)-(270, 180), 3, B LINE (265, 100)-(243, 127), 1, B, 21845 LINE (264, 101)-(244, 126), 1, B LINE (262, 103)-(246, 124), 2, B LOCATE 8, 16: PRINT "ENVELOPES" LOCATE 14, 7: PRINT "By:" LOCATE 17, 11: PRINT "Steve Dutch" LOCATE 18, 11: PRINT "Natural and Applied" LOCATE 19, 11: PRINT " Sciences" LOCATE 20, 11: PRINT "University of Wisconsin" LOCATE 21, 11: PRINT " - Green Bay" LOCATE 25, 1: PRINT "Press any key to continue"; U$ = INPUT$(1) SCREEN 0: WIDTH 80 PRINT "Envelopes are families of curves that define other, usually more" PRINT "complex, curves. Most students at some time or other have taken a" PRINT "sheet of graph paper, connected pairs of points like x=5,y=1; x=4,y=2" PRINT "and so on, with the total of x and y constant. The lines outline a curve." PRINT "This is a simple example of an envelope. (The curve is actually a" PRINT "parabola, and is one of the envelopes in this program.)" PRINT : PRINT "The performance of machinery like aircraft is usually bounded by" PRINT "limits that can be shown by curves on a graph. The area within all the limit" PRINT "curves is the region of possible performance. The boundary is an envelope." PRINT "When people speak of 'pushing the envelope', they are using the term" PRINT "'envelope' in the mathematical sense." PRINT : PRINT "To find the envelope of a family of curves, represent the curves as" PRINT "parametric functions x=f(t,c), y=g(t,c). For example, our simple envelope above" PRINT "is: x/a + y/c =1 (a+c=k; k constant), or x/(k-c)+y/c =1. We can write" PRINT "x=t(k-c), y=c(1-t). Find the formula (df/dt)(dg/dc)-(df/dc)(dg/dt)=0." PRINT "Using these formulas, eliminate c to find the envelope curve. We have" PRINT "df/dc=-t, df/dt=k-c, dg/dc=1-t, dg/dt=-c, hence (k-c)(1-t)+tc =0 and" PRINT "c=k(1-t)/(1+t-k). Hence x=tk(2-k)/(1+t-k) and y=k(1-t)^2/(1+t-k). After some" PRINT "unexpectedly complex algebra, we get:" COLOR 12 PRINT " 1/2 1/2" PRINT " x + y = k" COLOR 7 LOCATE 24, 1: PRINT "Press any key to continue"; U$ = INPUT$(1) INIT.MENU: CLS : REM MENU PRINT "1 - POLYGON" PRINT "2 - POLYGON WITH DIAGONALS" PRINT "3 - POLYGON PINWHEEL" PRINT "4 - POLYGON SPIRAL" PRINT "5 - PARABOLA I (WITH DURER'S CONCHOID" PRINT "6 - PARABOLA II (NEGATIVE PEDAL OF A LINE)" PRINT "7 - ELLIPSE" PRINT "8 - HYPERBOLA" PRINT "9 - ASTEROID I" PRINT "10 - ASTEROID II" PRINT "11 - LIMACONS AND CARDIOIDS" PRINT "12 - NEPHROID I" PRINT "13 - NEPHROID II" PRINT "14 - EPICYCLOID" PRINT "15 - HYPOCYCLOID" PRINT "16 - CYCLOID" PRINT "17 - LEMNISCATE OF BERNOULLI" PRINT "18 - RIGHT STROPHOID (AND RELATED CURVES)" COLOR 3: PRINT : PRINT "NOTE - IF NOT OTHERWISE INSTRUCTED, PRESS ANY KEY AFTER DISPLAY IS" PRINT "FINISHED TO RETURN TO PROGRAM" COLOR 7: LOCATE 25, 1: INPUT "DESIRED OPTION "; OP$ OP = VAL(OP$): IF OP < 1 OR OP > 18 THEN GOTO END.MENU ON OP GOTO PGON, PDI, PPW, PSP, PAR1, PAR2, ELL, HYP, AST1, AST2, LIM, NEPH1, NEPH2, EPIC, HYPO, CYC, LEMB, RTS PGON: REM POLYGON CLS : PRINT "More for fun than anything else. Star polygons are the interesting" PRINT "part. The meaning of a 5-sided polygon is clear, but what is a 5/2-sided" PRINT "polygon? A pentagon has vertices 360/5 degrees apart, and vertex angles of" PRINT "180(5-2)/5 or 108 degrees. Logically, a 5/2-sided polygon should have vertices" PRINT "360/(5/2) or 144 degrees apart, and vertex angles 180(5/2-2)/(5/2) or " PRINT "36 degrees. Thus, stars fit all the definitions of regular polygons." PRINT : PRINT "To draw star polygons, you have two choices. Input an integer for the number" PRINT "of sides, and a value > 1 for the offset interval (i.e. join faces more than one" PRINT "vertex apart) or enter a non-integer value for the number of faces." PRINT : PRINT "Cases where the number of sides and the offset have common factors result" PRINT "in somewhat degenerate cases. 6,2 results in the familiar Star of David, which" PRINT "is two overlapping equilateral triangles. Case 4,2 results in an eight-" PRINT "pointed star that is a common motif in the Middle East. It consists of" PRINT "two overlapping squares." PRINT : INPUT "NUMBER OF SIDES (DEFAULT = 3)"; NS$ NS = VAL(NS$): IF NS = 0 THEN NS = 3 INPUT "OFFSET INTERVAL (DEFAULT = 1) "; OS$ OS = VAL(OS$): IF OS = 0 THEN OS = 1 SCREEN 1 drawpoly = -1: I = 0 XA = XC + RC YA = YC XB = XC + RC * COS(2 * OS * PI / NS) YB = YC + RC * SIN(2 * OS * PI / NS) WHILE drawpoly drawpoly = 0 I = I + 1 X0 = XC + RC * COS(2 * I * PI / NS) Y0 = YC + RC * SIN(2 * I * PI / NS) X1 = XC + RC * COS(2 * (I + OS) * PI / NS) Y1 = YC + RC * SIN(2 * (I + OS) * PI / NS) LINE (X0, Y0)-(X1, Y1) IF ABS(X0 - XA) > 1 THEN drawpoly = -1 IF ABS(Y0 - YA) > 1 THEN drawpoly = -1 IF ABS(X1 - XB) > 1 THEN drawpoly = -1 IF ABS(Y1 - YB) > 1 THEN drawpoly = -1 IF I > 1000 THEN drawpoly = 0 WEND a$ = INPUT$(1): GOTO END.MENU PDI: REM POLYGON WITH DIAGONALS CLS : PRINT "Mostly for fun. Draws a polygon with all diagonals" PRINT : INPUT "NUMBER OF SIDES (DEFAULT = 4) "; NS$ NS = INT(VAL(NS$)): IF NS < 3 THEN NS = 4 SCREEN 1 FOR I = 1 TO NS: FOR J = 1 TO NS - I X0 = XC + RC * COS(2 * I * PI / NS) Y0 = YC + RC * SIN(2 * I * PI / NS) X1 = XC + RC * COS(2 * (I + J) * PI / NS) Y1 = YC + RC * SIN(2 * (I + J) * PI / NS) LINE (X0, Y0)-(X1, Y1) NEXT J NEXT I a$ = INPUT$(1): GOTO END.MENU PPW: REM POLYGON PINWHEEL CLS : PRINT "Mostly for fun. Draws regular polygons that spiral outward" PRINT : INPUT "NUMBER OF SIDES (DEFAULT = 3) "; NS$ NS = INT(VAL(NS$)): IF NS < 3 THEN NS = 3 INPUT "RADIUS INCREASE FACTOR PER REVOLUTION (DEFAULT =1.1) "; df$ df = VAL(df$): IF df < 1 THEN df = 1.1 INPUT "ANGLE OFFSET PER REVOLUTION (DEFAULT = 0) "; AO$ AO = VAL(AO$): AO = PI * AO / 180 R0 = 10: DA = 2 * PI / NS: DAO = 0 SCREEN 1 WHILE R0 <= RC FOR I = 1 TO NS X0 = XC + R0 * COS(I * DA + DAO) Y0 = YC + R0 * SIN(I * DA + DAO) X1 = XC + R0 * COS((I + 1) * DA + DAO) Y1 = YC + R0 * SIN((I + 1) * DA + DAO) LINE (X0, Y0)-(X1, Y1) NEXT I R0 = R0 * df: DAO = DAO + AO WEND a$ = INPUT$(1): GOTO END.MENU PSP: REM 4 - POLYGON SPIRAL CLS : PRINT "Mostly for fun. Draws a continuous polygon spiral. If the number of" PRINT "sides is not an integer, star patterns result." PRINT : INPUT "NUMBER OF SIDES (DEFAULT = 3) "; NS$ NS = VAL(NS$): IF NS = 0 THEN NS = 3 INPUT "RADIUS INCREASE FACTOR PER REVOLUTION (DEFAULT =1.1) "; df$ df = VAL(df$): IF df < 1 THEN df = 1.1 INPUT "ANGLE OFFSET PER REVOLUTION (DEFAULT = 0) "; AO$ DF1 = df ^ (1 / NS): AO = VAL(AO$): AO = (AO * PI / 180) / NS R0 = 10: R1 = R0 * DF1 SCREEN 1 DA = 2 * PI / NS + AO: I = 0 WHILE RC > R1 X0 = XC + R0 * COS(I * DA) Y0 = YC + R0 * SIN(I * DA) X1 = XC + R1 * COS((I + 1) * DA) Y1 = YC + R1 * SIN((I + 1) * DA) LINE (X0, Y0)-(X1, Y1) R0 = R1: R1 = R1 * DF1: I = I + 1 WEND a$ = INPUT$(1): GOTO END.MENU PAR1: REM"5 - PARABOLA I" CLS : PRINT "IF A SERIES OF LINES IS DRAWN SUCH THAT THE SUM OF THEIR X- AND Y-" PRINT "INTERCEPTS IS CONSTANT, THE ENVELOPE OF THE LINES IS A PARABOLA." PRINT : PRINT "ITS EQUATION IS: 1/2 1/2": PRINT " X + Y = CONSTANT" RINT: INPUT "SUM OF INTERCEPTS (DEFAULT = 50) "; XY$ XY = VAL(XY$): IF XY = 0 THEN XY = 50 INPUT "INCREMENT (DEFAULT = 10) "; DX$ DX = VAL(DX$): IF DX = 0 THEN DX = 10 PRINT : PRINT " DURER'S CONCHOID" PRINT "DURER'S CONCHOID IS DRAWN BY MARKING OFF POINTS ON EACH" PRINT "LINE OF THE ENVELOPE AN EQUAL DISTANCE FROM THE X-AXIS. " PRINT "DESPITE THIS SIMPLE DEFINITION, THE EQUATION OF THE CURVE IS" PRINT "VERY COMPLEX:": PRINT PRINT " 2 2 2 2 2 2 2 2 2 2 2 2 2" PRINT "2Y (X + Y )-2BY (X + Y)+Y (B -3A )-A X +2A B(X + Y)+A (A -B ) = 0" PRINT : PRINT "A IS THE DISTANCE FROM THE X-AXIS; B IS THE SUM OF THE INTERCEPTS" PRINT : INPUT "SHOW DURER'S CONCHOID - Y/N (DEFAULT = NO) "; dc$ IF dc$ <> "Y" THEN dc$ = "N" IF dc$ = "Y" THEN PRINT "INPUT DISTANCE FROM X-AXIS" INPUT " (DEFAULT = SUM OF INTERCEPTS) "; D0$ D0 = VAL(D0$): IF D0 = 0 THEN D0 = XY END IF CC = 3: IF dc$ = "Y" THEN CC = 1 SCREEN 1 LINE (0, 3 * YC / 2)-(320, 3 * YC / 2), 2 LINE (XC / 2, 0)-(XC / 2, 200), 2 DCX1A = 0: DCY1A = 3 * YC / 2 - D0 * .707 DCX2A = 0: DCY2A = 3 * YC / 2 + D0 * .707 FOR X = -XC / 2 TO 320 - XC / 2 STEP DX: Y = XY - X IF Y <> 0 AND X <> 0 THEN X1 = XC / 2 + (X * Y - X * 3 * YC / 2) / Y: Y1 = 0 X2 = XC / 2 + (X * Y + X * YC / 2) / Y: Y2 = 200 END IF LINE (X1, Y1)-(X2, Y2), CC IF dc$ = "Y" THEN L = SQR(X * X + Y * Y): DX0 = X * D0 / L: DY0 = Y * D0 / L DCX1B = XC / 2 + X - DX0: DCY1B = 3 * YC / 2 - DY0 DCX2B = XC / 2 + X + DX0: DCY2B = 3 * YC / 2 + DY0 LINE (DCX1A, DCY1A)-(DCX1B, DCY1B), 3 LINE (DCX2A, DCY2A)-(DCX2B, DCY2B), 3 DCX1A = DCX1B: DCY1A = DCY1B: DCX2A = DCX2B: DCY2A = DCY2B END IF NEXT X a$ = INPUT$(1): GOTO END.MENU PAR2: REM"6 - PARABOLA II" CLS : PRINT "THE PARABOLA IS THE NEGATIVE PEDAL OF A LINE WITH RESPECT TO A POINT" PRINT "NOT ON THE LINE. THAT IS, IF A RADIUS IS DRAWN FROM THE POINT TO THE LINE," PRINT "AND THEN PERPENDICULAR LINES DRAWN AT THE POINT OF INTERSECTION, THE" PRINT "ENVELOPE OF THE PERPENDICULAR LINES IS A PARABOLA." PRINT : INPUT "DISTANCE FROM FOCUS TO DIRECTRIX (DEFAULT = 40) "; HF$: HF = VAL(HF$) IF HF <= 0 THEN HF = 40 INPUT "ANGLE INTERVAL (DEFAULT = 10) "; DA$: DA = VAL(DA$) IF DA = 0 THEN DA = 10 SCREEN 1: CLS LINE (0, 195)-(319, 195), 2 FOR t = 0 TO ATN(160 / HF) * 180 / PI STEP DA T0 = t * PI / 180 LINE (XC, 195 - HF)-(XC + HF * TAN(T0), 195), 1 LINE (XC, 195 - HF)-(XC - HF * TAN(T0), 195), 1 IF t = 0 THEN 1160 1160 LINE (XC + HF * TAN(T0), 195)-(319, 195 - (160 - HF * TAN(T0)) * TAN(T0)) 1170 LINE (XC - HF * TAN(T0), 195)-(0, 195 - (160 - HF * TAN(T0)) * TAN(T0)) NEXT t a$ = INPUT$(1): GOTO END.MENU ELL: REM "7 - ELLIPSE" CLS : PRINT "THE ELLIPSE IS THE NEGATIVE PEDAL OF A CIRCLE WITH RESPECT TO" PRINT "AN INTERIOR POINT. IF RADII ARE DRAWN FROM THE POINT TO THE CIRCLE," PRINT "PERPENDICULARS TO THE RADII FORM THE ENVELOPE OF THE ELLIPSE." PRINT "THE INTERIOR POINT IS THE FOCUS OF THE ELLIPSE" PRINT : INPUT "INPUT ECCENTRICITY (DEFAULT =0.7) "; E$: E = VAL(E$) IF E <= 0 OR E >= 1 THEN E = .7 AE = E * RC: XF = XC + AE: YF = YC INPUT "INPUT ANGLE INCREMENT (DEFAULT = 10) "; DA$: DA = VAL(DA$) IF DA <= 0 THEN DA = 10 INPUT "SHOW RADII - Y/N (DEFAULT = YES) "; YN$ IF YN$ <> "N" THEN YN$ = "Y" SCREEN 1: CLS CX = XC: CY = YC: RAD = RC: CC = 3: CALL DRAW.CIRCLE(CX, CY, RAD, CC) FOR t = 0 TO 180 STEP DA a = t * PI / 180 SB = AE * SIN(a) / RC: B = ATN(SB / SQR(1 - SB * SB)): C = PI - a - B X0 = XC + RC * COS(C): Y0 = YC + RC * SIN(C) X2 = XC + RC * COS(C + 2 * B): Y2 = YC + RC * SIN(C + 2 * B) LINE (X0, Y0)-(X2, Y2), 3 IF YN$ = "Y" THEN LINE (X0, Y0)-(XF, YF), 1 NEXT t FOR t = 0 TO -180 STEP -DA a = t * PI / 180 SB = AE * SIN(a) / RC: B = ATN(SB / SQR(1 - SB * SB)): C = PI - a - B X0 = XC + RC * COS(C): Y0 = YC + RC * SIN(C) X2 = XC + RC * COS(C + 2 * B): Y2 = YC + RC * SIN(C + 2 * B) LINE (X0, Y0)-(X2, Y2), 3 IF YN$ = "Y" THEN LINE (X0, Y0)-(XF, YF), 1 NEXT t LINE (XF - 2, YF - 2)-(XF + 2, YF + 2), 2, BF LINE (XF - 1, YF - 1)-(XF + 1, YF + 1), 0, B a$ = INPUT$(1): GOTO END.MENU HYP: REM"8 - HYPERBOLA" CLS : PRINT "THE HYPERBOLA IS THE NEGATIVE PEDAL OF A CIRCLE WITH RESPECT TO" PRINT "AN EXTERIOR POINT. IF RADII ARE DRAWN FROM THE POINT TO THE CIRCLE," PRINT "PERPENDICULARS TO THE RADII FORM THE ENVELOPE OF THE HYPERBOLA." PRINT "THE EXTERIOR POINT IS THE FOCUS OF THE HYPERBOLA." PRINT : INPUT "INPUT ECCENTRICITY (DEFAULT = SQR(2) "; E$ E = VAL(E$): IF E < 1 THEN E = SQR(2) INPUT "INPUT GENERATOR CIRCLE RADIUS (DEFAULT = 40) "; GR$ GR = VAL(GR$): IF GR <= 0 THEN GR = 40 AE = E * GR: XF1 = XC + AE: XF2 = XC - AE: YF = YC IF AE > 150 THEN AE = 150: GR = AE / E XF1 = XC + AE: XF2 = XC - AE: YF = YC INPUT "INPUT ANGLE INCREMENT (DEFAULT = 10) "; DA$ DA = VAL(DA$): IF DA <= 0 THEN DA = 10 INPUT "SHOW RADII - Y/N (DEFAULT = NO) "; YN$ IF YN$ <> "Y" THEN YN$ = "N" INPUT "SHOW BRANCHES - LEFT/RIGHT/BOTH (DEFAULT = BOTH) "; BR$ IF BR$ <> "L" AND BR$ <> "R" THEN BR$ = "B" SCREEN 1: CLS CX = XC: CY = YC: RAD = GR: CC = 3: CALL DRAW.CIRCLE(CX, CY, RAD, CC) REM LEFT BRANCH IF BR$ = "L" OR BR$ = "B" THEN REM SET ANGLE LIMITS LA = ATN(SQR(AE * AE - GR * GR) / GR) * 180 / PI FOR t = LA TO 360 - LA STEP DA a = t * PI / 180 B = ATN(GR * SIN(a) / (AE - GR * COS(a))) X0 = XC + GR * COS(a): Y0 = YC + GR * SIN(a) X1 = X0 + 200 * SIN(B): Y1 = Y0 + 200 * COS(B) IF t < 180 THEN X1 = X0 - 200 * SIN(B): Y1 = Y0 - 200 * COS(B) LINE (X0, Y0)-(X1, Y1), 3 IF YN$ = "Y" THEN LINE (X0, Y0)-(XF1, YF), 1 NEXT t END IF REM RIGHT BRANCH IF BR$ = "R" OR BR$ = "B" THEN REM SET ANGLE LIMITS LA = ATN(SQR(AE * AE - GR * GR) / GR) * 180 / PI FOR t = LA - 180 TO 180 - LA STEP DA a = t * PI / 180 B = ATN(GR * SIN(a) / (AE + GR * COS(a))) X0 = XC + GR * COS(a): Y0 = YC + GR * SIN(a) X1 = X0 + 200 * SIN(B): Y1 = Y0 - 200 * COS(B) IF t < 0 THEN X1 = X0 - 200 * SIN(B): Y1 = Y0 + 200 * COS(B) LINE (X0, Y0)-(X1, Y1), 3 IF YN$ = "Y" THEN LINE (X0, Y0)-(XF2, YF), 1 NEXT t END IF REM DRAW FOCI LINE (XF2 - 2, YF - 2)-(XF2 + 2, YF + 2), 2, BF LINE (XF2 - 1, YF - 1)-(XF2 + 1, YF + 1), 0, B LINE (XF1 - 2, YF - 2)-(XF1 + 2, YF + 2), 2, BF LINE (XF1 - 1, YF - 1)-(XF1 + 1, YF + 1), 0, B REM DRAW ASYMPTOTES LX = 100 * GR / SQR(AE * AE - GR * GR) LINE (XC - LX, YC - 100)-(XC + LX, YC + 100), 2 LINE (XC + LX, YC - 100)-(XC - LX, YC + 100), 2 a$ = INPUT$(1): GOTO END.MENU AST1: REM"9 - ASTEROID I" CLS : SCREEN 0: WIDTH 80: PRINT "ASTEROID IS THE ENVELOPE OF ELLIPSES WHOSE MAJOR AND MINOR": PRINT "AXES HAVE A CONSTANT SUM" PRINT : PRINT "ITS EQUATION IS: 2/3 2/3": PRINT " X + Y = 1" PRINT : INPUT "AXIS LENGTH INCREMENT (DEFAULT =10) "; DL$ DL = VAL(DL$): IF DL <= 0 OR DL > RC THEN DL = 10 SCREEN 1: CLS : LINE (XC, YC - RC)-(XC, YC + RC): LINE (XC - RC, YC)-(XC + RC, YC) FOR a = 0 TO RC STEP DL: B = RC - a: X0 = a: Y0 = 0 FOR t = 0 TO .52 * PI STEP .02 * PI X1 = a * COS(t): Y1 = B * SIN(t) LINE (XC + X0, YC + Y0)-(XC + X1, YC + Y1): LINE (XC - X0, YC + Y0)-(XC - X1, YC + Y1) LINE (XC + X0, YC - Y0)-(XC + X1, YC - Y1): LINE (XC - X0, YC - Y0)-(XC - X1, YC - Y1) X0 = X1: Y0 = Y1 NEXT t NEXT a a$ = INPUT$(1): GOTO END.MENU AST2: REM"10 - ASTEROID II" CLS : PRINT "ASTEROID AS THE ENVELOPE OF A LINE OF CONSTANT LENGTH" PRINT "SLIDING ALONG TWO PERPENDICULAR LINES (GLISSETTE)" PRINT : PRINT "ITS EQUATION IS: 2/3 2/3": PRINT " X + Y = 1" PRINT : INPUT "INPUT ANGLE INCREMENT IN DEGREES (DEFAULT = 10) "; a$ a = VAL(a$): IF a <= 0 THEN a = 10 SCREEN 1: CLS : LINE (XC, YC - RC)-(XC, YC + RC): LINE (XC - RC, YC)-(XC + RC, YC) FOR I = 0 TO 90 STEP a DX = RC * COS(I * PI / 180): DY = RC * SIN(I * PI / 180) LINE (XC + DX, YC)-(XC, YC - DY) LINE (XC + DX, YC)-(XC, YC + DY) LINE (XC - DX, YC)-(XC, YC - DY) LINE (XC - DX, YC)-(XC, YC + DY) NEXT I a$ = INPUT$(1): GOTO END.MENU LIM: REM"11 - LIMACONS AND CARDIOIDS" CLS : PRINT "LIMACONS AND CARDIOIDS ARE FORMED BY ROLLING A CIRCLE AROUND A FIXED" PRINT "CIRCLE OF EQUAL RADIUS. A POINT ATTACHED TO THE ROLLING CIRCLE" PRINT "TRACES OUT THE CURVE. THE CURVE CAN ALSO BE TRACED OUT AS AN" PRINT "ENVELOPE OF CIRCLES CENTERED ON A FIXED CIRCLE AND PASSING THROUGH A" PRINT "FIXED POINT." PRINT : INPUT "INPUT RADIUS RATIO (DEFAULT = 1) "; RR$: RR = VAL(RR$) IF RR <= 0 THEN RR = 1 INPUT "INTERVAL (DEFAULT = 10) "; DA$: DA = VAL(DA$) IF DA = 0 THEN DA = 10 SCREEN 1: CLS CX = XC: CY = YC: CC = 2: RAD = RC / (1.5 + RR): IF RR < 1 THEN RAD = RC / (2 + RR / 2) CALL DRAW.CIRCLE(CX, CY, RAD, CC) XP = XC - RAD * RR: YP = YC: R1 = RAD FOR T1 = 0 TO 360 STEP DA: T0 = T1 * PI / 180 CX = XC + R1 * COS(T0): CY = YC + R1 * SIN(T0) RAD = SQR((CX - XP) ^ 2 + (CY - YP) ^ 2): CC = 3 CALL DRAW.CIRCLE(CX, CY, RAD, CC) NEXT T1 a$ = INPUT$(1): GOTO END.MENU NEPH1: REM" 12 - NEPHROID I" CLS : PRINT "A NEPHROID IS THE CURVE TRACED OUT BY A POINT ON THE CIRCUMFERENCE" PRINT "OF A ROLLING CIRCLE AS IT ROLLS AROUND A FIXED CIRCLE WITH A RADIUS" PRINT "TWICE AS LARGE.": PRINT : PRINT "IT CAN ALSO BE CONSTRUCTED BY DRAWING A SERIES OF" PRINT "CIRCLES CENTERED ON THE FIXED CIRCLE, AND TANGENT TO A DIAMETER OF IT." PRINT : INPUT "ANGLE INTERVAL (DEFAULT = 10) "; DA$: DA = VAL(DA$) IF DA = 0 THEN DA = 10 SCREEN 1: CLS CC = 2: CX = XC: CY = YC: RAD = 2 * RC / 3: CALL DRAW.CIRCLE(CX, CY, RAD, CC) LINE (CX, CY - RAD)-(CX, CY + RAD), CC R1 = RAD: CC = 3 FOR T1 = 0 TO 90 STEP DA: T0 = T1 * PI / 180 CX = XC + R1 * COS(T0): CY = YC + R1 * SIN(T0): RAD = R1 * COS(T0) CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = XC + R1 * COS(T0): CY = YC - R1 * SIN(T0): RAD = R1 * COS(T0) CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = XC - R1 * COS(T0): CY = YC - R1 * SIN(T0): RAD = R1 * COS(T0) CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = XC - R1 * COS(T0): CY = YC + R1 * SIN(T0): RAD = R1 * COS(T0) CALL DRAW.CIRCLE(CX, CY, RAD, CC) NEXT T1 LINE (CX, CY - RAD)-(CX, CY + RAD), CC a$ = INPUT$(1): GOTO END.MENU NEPH2: REM"13 - NEPHROID II" CLS : PRINT "A NEPHROID IS THE CURVE TRACED OUT BY A POINT ON THE CIRCUMFERENCE" PRINT "OF A ROLLING CIRCLE AS IT ROLLS AROUND A FIXED CIRCLE WITH A RADIUS" PRINT "TWICE AS LARGE.": PRINT : PRINT "IT CAN ALSO BE CONSTRUCTED BY LOCATING POINTS ON A" PRINT "DIAMETER OF THE FIXED CIRCLE, MEASURING THE DISTANCE TO THE CENTER" PRINT "OF THE CIRCLE, AND DRAWING A LINE OF THE SAME LENGTH TO THE" PRINT "EDGE OF THE CIRCLE." PRINT : INPUT "ANGLE INTERVAL (DEFAULT = 5) "; DA$: DA = VAL(DA$) IF DA = 0 THEN DA = 5 SCREEN 1: CLS LINE (0, YC)-(319, YC), 2: LINE (XC, YC - 3)-(XC, YC + 3), 2 CX = XC: CY = YC: RAD = 80: CC = 2: CALL DRAW.CIRCLE(CX, CY, RAD, CC) FOR t = 0 TO ATN(SQR(320 ^ 2 - RAD ^ 2) / RAD) STEP DA * PI / 180 R = RAD / (2 * COS(t)) LINE (XC + R, YC)-(XC + RAD * COS(t), YC + RAD * SIN(t)) LINE (XC + R, YC)-(XC + RAD * COS(t), YC - RAD * SIN(t)) LINE (XC - R, YC)-(XC - RAD * COS(t), YC + RAD * SIN(t)) LINE (XC - R, YC)-(XC - RAD * COS(t), YC - RAD * SIN(t)) NEXT t a$ = INPUT$(1): GOTO END.MENU EPIC: REM"14 - EPICYCLOID" CLS : PRINT "AN EPICYCLOID IS THE CURVE TRACED OUT BY A POINT ON A ROLLING CIRCLE AS IT": PRINT "ROLLS AROUND ANOTHER FIXED CIRCLE. IF THE FIXED CIRCLE HAS A RADIUS" PRINT "N TIMES THAT OF THE ROLLING CIRCLE, THE CURVE WILL HAVE N LOBES.": PRINT "IF N = 1 THE CURVE IS A CARDIOID, IF N = 2 IT IS A NEPHROID." PRINT : PRINT "IT IS ALSO POSSIBLE TO CONSTRUCT AN EPICYCLOID AS AN ENVELOPE. DRAW A LINE": PRINT "FROM A POINT AT AZIMUTH A ON A CIRCLE TO AZIMUTH (N+1)A. THE ENVELOPE" PRINT "OF LINES IS AN EPICYCLOID OF N LOBES." PRINT : PRINT "IF N IS LARGE, THE CONSTRUCTION CAN BE MESSY. THUS, IT IS ADVISABLE TO SHOW": PRINT "ONLY THE NECESSARY PART OF EACH LINE FOR LARGE N." PRINT : INPUT "ANGLE INTERVAL (DEFAULT = 10) "; DA$: DA = VAL(DA$) IF DA = 0 THEN DA = 10 INPUT "NUMBER OF LOBES (DEFAULT = 1) "; NL$: NL = VAL(NL$) + 1 IF NL < 2 THEN NL = 2 PRINT "SHOW ALL LINES - Y/N? (DEFAULT = NO) ": SH$ = INPUT$(1) IF SH$ <> "Y" THEN SH$ = "N" SCREEN 1: CLS CX = XC: CY = YC: RAD = RC: CC = 3: CALL DRAW.CIRCLE(CX, CY, RAD, CC) FOR t = 0 TO 360 STEP DA X0 = XC + RC * COS(t * PI / 180): Y0 = YC + RC * SIN(t * PI / 180) X1 = XC + RC * COS(t * NL * PI / 180): Y1 = YC + RC * SIN(t * NL * PI / 180) LINE (X0, Y0)-(X0 + (X1 - X0) / (NL + 1), Y0 + (Y1 - Y0) / (NL + 1)) IF SH$ = "Y" THEN LINE (X0 + (X1 - X0) / (NL + 1), Y0 + (Y1 - Y0) / (NL + 1))-(X1, Y1), 1 NEXT t a$ = INPUT$(1): GOTO END.MENU HYPO: REM HYPOCYCLOIDS CLS : PRINT "A HYPOCYCLOID IS THE CURVE TRACED OUT BY A POINT ON A ROLLING CIRCLE AS IT" PRINT "ROLLS AROUND THE INSIDE OF ANOTHER FIXED CIRCLE. IF THE FIXED CIRCLE HAS A" PRINT "RADIUS N TIMES THAT OF THE ROLLING CIRCLE, THE CURVE WILL HAVE N CUSPS." PRINT : PRINT "IT IS ALSO POSSIBLE TO CONSTRUCT A HYPOCYCLOID AS THE ENVELOPE SWEPT OUT" PRINT "BY THE DIAMETER OF A CIRCLE ROLLING INSIDE THE FIXED CIRCLE. IN THIS CASE THE" PRINT "ROLLING CIRCLE HAS RADIUS 2/N TIMES THAT OF THE FIXED CIRCLE." XO = 160: YO = 90: RO = 80 N = 0: WHILE N <= 0 PRINT : INPUT "INPUT NUMBER OF CUSPS "; N$ N = VAL(N$) WEND RI = RO * 2 / N SCREEN 1: CLS X0 = XO + RO: Y0 = YO FOR t = 0 TO 2 * PI STEP .01 X1 = XO + RO * COS(t): Y1 = YO - RO * SIN(t) LINE (X0, Y0)-(X1, Y1), 3 X0 = X1: Y0 = Y1 NEXT t REM NOW DRAW HYPOCYCLOID AS ENVELOPE OF DIAMETER OF ROLLING CIRCLE DR = RO - RI: t = 0: XD1 = 0: XD2 = 0 TSTEP = PI / (10 * N) STOPDRAW = 0 WHILE NOT STOPDRAW XI = XO + DR * COS(t): YI = YO - DR * SIN(t) TI = t - t * RO / RI IF t > 0 AND t < 50 * PI THEN STOPDRAW = -1 IF ABS(SIN(t)) > .005 THEN STOPDRAW = 0 IF COS(t) < .995 THEN STOPDRAW = 0 IF ABS(SIN(TI)) > .01 THEN STOPDRAW = 0 IF ABS(COS(TI)) < .995 THEN STOPDRAW = 0 XD1 = XI + RI * COS(TI): YD1 = YI - RI * SIN(TI) XD2 = XI - RI * COS(TI): YD2 = YI + RI * SIN(TI) LINE (XD1, YD1)-(XD2, YD2), 3 t = t + TSTEP WEND a$ = INPUT$(1): GOTO END.MENU CYC: REM CYCLOIDS CLS : PRINT "A CYCLOID IS THE CURVE TRACED OUT BY A POINT ON A ROLLING CIRCLE AS IT" PRINT "ROLLS ALONG A STRAIGHT LINE." PRINT : PRINT "IT IS ALSO POSSIBLE TO CONSTRUCT A CYCLOID AS THE ENVELOPE SWEPT OUT" PRINT "BY THE DIAMETER OF A CIRCLE ROLLING ALONG A STRAIGHT LINE." PRINT : PRINT "PRESS ANY KEY TO CONTINUE" U$ = INPUT$(1) Y = 120: R = 30 SCREEN 1 LINE (0, Y)-(320, Y) FOR t = 0 TO 4 * PI STEP PI / 20 X = R * t X1 = X + R * SIN(t): Y1 = Y - R - R * COS(t) X2 = X - R * SIN(t): Y2 = Y - R + R * COS(t) REM SIN & COS SWITCHED TO GIVE PI/2 PHASE SHIFT LINE (X1, Y1)-(X2, Y2) NEXT t U$ = INPUT$(1): GOTO END.MENU LEMB: REM LEMNISCATE OF BERNOULLI CLS : PRINT "Construct a rectangular hyperbola (e ="; CHR$(251); "2). From each point on" PRINT "the hyperbola, construct a circle passing through the center of the" PRINT "hyperbola. The circles outline the Lemniscate of Bernoulli." PRINT : PRINT "PRESS ANY KEY TO CONTINUE" U$ = INPUT$(1) SCREEN 1 XC = 160: YC = 95: R0 = 50 X0 = R0: Y0 = 0 FOR X = R0 TO SQR(YC * YC + R0 * R0) Y = SQR(X * X - R0 * R0) LINE (XC + X0, YC + Y0)-(XC + X, YC + Y), 2 LINE (XC + X0, YC - Y0)-(XC + X, YC - Y), 2 LINE (XC - X0, YC + Y0)-(XC - X, YC + Y), 2 LINE (XC - X0, YC - Y0)-(XC - X, YC - Y), 2 X0 = X: Y0 = Y NEXT X X0 = R0: Y0 = 0 FOR Y = 0 TO YC STEP 5 X = SQR(Y * Y + R0 * R0) RAD = SQR(X * X + Y * Y) CX = XC + X: CY = YC + Y: CC = 3 CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = XC - X: CY = YC + Y CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = XC - X: CY = YC - Y CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = XC + X: CY = YC - Y CALL DRAW.CIRCLE(CX, CY, RAD, CC) NEXT Y U$ = INPUT$(1): GOTO END.MENU RTS: CLS : PRINT "A variety of interesting curves result from circles centered on a parabola." PRINT "If the circles pass through the focus, the curve is a straight line. Recall" PRINT "that a parabola is the locus of points equidistant from a point and a line." PRINT "The line is called the DIRECTRIX" PRINT : PRINT "If the circles pass through the vertex, the curve is the CISSOID OF DIOCLES." PRINT : PRINT "If the circles pass through the intersection of the axis and the directrix," PRINT "the curve is the RIGHT STROPHOID." PRINT : PRINT "If the circles pass through a point on the axis, the same distance beyond" PRINT "the directrix as the focus, the curve is the TRISECTRIX OF MACLAURIN." selectcurve: LOCATE 14, 1: PRINT "Type in the curve you want to display:" PRINT " 1 - DIRECTRIX" PRINT " 2 - CISSOID OF DIOCLES" PRINT " 3 - RIGHT STROPHOID" PRINT " 4 - TRISECTRIX OF MACLAURIN" PRINT : INPUT "Select Curve "; C$ C = INT(VAL(C$)): IF C < 1 OR C > 4 THEN GOTO selectcurve CLS : SCREEN 1 XC = 140: YC = 95: RF = 25 X0 = XC - RF: Y0 = 0 FOR Y = 0 TO YC X = RF * (Y / RF) * (Y / RF) / 4 + XC - RF LINE (X0, YC + Y0)-(X, YC + Y), 2 LINE (X0, YC - Y0)-(X, YC - Y), 2 X0 = X: Y0 = Y NEXT Y LINE (XC - 2 * RF, 0)-(XC - 2 * RF, 190), 1 IF C = 1 THEN XP = XC IF C = 2 THEN XP = XC - RF IF C = 3 THEN XP = XC - 2 * RF IF C = 4 THEN XP = XC - 4 * RF FOR Y = 0 TO YC STEP 3 X = RF * (Y / RF) * (Y / RF) / 4 + XC - RF RAD = SQR((X - XP) * (X - XP) + Y * Y) CX = X: CY = YC + Y: CC = 3 CALL DRAW.CIRCLE(CX, CY, RAD, CC) CX = X: CY = YC - Y: CC = 3 CALL DRAW.CIRCLE(CX, CY, RAD, CC) NEXT Y U$ = INPUT$(1): GOTO END.MENU END.MENU: SCREEN 0: WIDTH 80: CLS PRINT "DO SOME MORE - Y/N ": YN$ = INPUT$(1) IF YN$ = "Y" OR YN$ = "y" THEN GOTO INIT.MENU END SUB DRAW.CIRCLE (CX, CY, RAD, CC) REM DRAW CIRCLES REM THE CIRCLE COMMAND IS USELESS FOR SERIOUS MATH BECAUSE REM IT DOES NOT DRAW TRUE CIRCLES WITH DEFAULT PARAMETERS IF ABS(RAD) < .5 THEN PSET (CX, CY), CC GOTO quit.draw.circle END IF STP = 1 / RAD: IF STP < .02 * PI THEN STP = .02 * PI X0 = RAD: Y0 = 0: FOR t = 0 TO .52 * PI STEP STP X1 = RAD * COS(t): Y1 = RAD * SIN(t) LINE (CX + X0, CY + Y0)-(CX + X1, CY + Y1), CC: LINE (CX - X0, CY + Y0)-(CX - X1, CY + Y1), CC LINE (CX + X0, CY - Y0)-(CX + X1, CY - Y1), CC: LINE (CX - X0, CY - Y0)-(CX - X1, CY - Y1), CC X0 = X1: Y0 = Y1: NEXT t quit.draw.circle: END SUB