DECLARE FUNCTION RandomFunction! () DECLARE FUNCTION RandomReal! () DECLARE SUB DrawGrid () DECLARE SUB AutoFitY () DECLARE SUB SamplesMenu () DECLARE SUB RandomChange () DECLARE FUNCTION GetLimit! (lim!, l$) DECLARE SUB ResetVariables () DECLARE SUB PrintInfo () DECLARE SUB PrintFunction () DECLARE FUNCTION fstring$ (c$, x$, n!) DECLARE FUNCTION GetConstant! (c!, const$) DECLARE FUNCTION GetFunction! (n!, f$, c$, x$) DECLARE SUB DrawAxes () DECLARE SUB PlotPoint (x!, y!) DECLARE SUB DrawPoint (xc!, yc!, colour!, s!) DECLARE SUB DrawGraph () DECLARE SUB DrawBox () DECLARE FUNCTION fc! (x!, c1!, c2!, n1!, n2!, n!) DECLARE FUNCTION func! (x!, c!, n!) SCREEN 12 RANDOMIZE TIMER ' Global constants ' Screen graphics DIM SHARED gxmin, gxmax, gymin, gymax, gxdiff, gydiff gxmin = 0: gxmax = 396: gymin = 0: gymax = 396 gxdiff = gxmax - gxmin: gydiff = gymax - gymin DIM SHARED symax symax = 480 ' Screen colours DIM SHARED black, green, blue, red, white black = 0: green = 2: blue = 3: red = 4: white = 15 DIM SHARED pointcolour, boxcolour, axiscolour, gridcolour pointcolour = red: boxcolour = white: axiscolour = blue: gridcolour = green ' Screen words DIM SHARED xloc, yloc, dxloc xloc = 52: yloc = 26 ' Mathematics DIM SHARED Pi Pi = 3.1415927# ' Functions DIM SHARED nfunctions nfunctions = 18 ' User constants ' Screen dimensions DIM SHARED xmin, xmax, ymin, ymax, xstep, ystep, gxstep ' Graph functions DIM SHARED a, b, g, h, f, pointsize ' Booleans DIM SHARED autofit CALL ResetVariables ' Main Loop DO CLS CALL DrawBox IF autofit = 1 THEN CALL AutoFitY CALL DrawGrid CALL DrawAxes CALL DrawGraph CALL PrintInfo DO a$ = INKEY$ SELECT CASE LCASE$(a$) CASE "a": a = GetConstant(a, "a") CASE "b": b = GetConstant(b, "b") CASE "c": CALL RandomChange CASE "d": DO gxstep = GetConstant(gxstep, "point density") IF gxstep <= 0 THEN PRINT "Point density must be greater than zero." LOOP WHILE gxstep <= 0 CASE "f": f = GetFunction(f, "f", "g", "h") CASE "g": g = GetFunction(g, "g", "a", "x") CASE "h": h = GetFunction(h, "h", "b", "x") CASE "m": CALL SamplesMenu CASE "p": pointsize = GetConstant(pointsize, "point size") CASE "r": CALL ResetVariables CASE "s": xmin = GetLimit(xmin, "xmin") CASE "t": xmax = GetLimit(xmax, "xmax") CASE "u": ymin = GetLimit(ymin, "ymin") CASE "v": ymax = GetLimit(ymax, "ymax") CASE "y": autofit = -autofit CASE CHR$(27): SYSTEM 'Esc END SELECT LOOP WHILE a$ = "" LOOP SUB AutoFitY FOR gx = gxmin TO gxmax x = xmin + (xmax - xmin) * (gx - gxmin) / gxdiff y = fc(x, a, b, g, h, f) IF y < ymin OR gx = gxmin THEN ymin = y IF y > ymax OR gx = gxmin THEN ymax = y NEXT gx IF ymax = ymin THEN ymin = -5 ymax = 5 END IF END SUB SUB DrawAxes gx0 = gxmin + gxdiff * (0 - xmin) / (xmax - xmin) gy0 = gymin + gydiff * (0 - ymin) / (ymax - ymin) IF gx0 >= gxmin AND gx0 <= gxmax THEN LINE (gx0, gymin)-(gx0, gymax), axiscolour IF gy0 >= gymin AND gy0 <= gymax THEN LINE (gxmin, gymax - gy0)-(gxmax, gymax - gy0), axiscolour END SUB SUB DrawBox LINE (gxmin, gymin)-(gxmax, gymax), boxcolour, B END SUB SUB DrawGraph FOR gx = gxmin TO gxmax STEP 1 / gxstep x = xmin + (xmax - xmin) * (gx - gxmin) / gxdiff y = fc(x, a, b, g, h, f) IF x >= xmin AND x <= xmax AND y >= ymin AND y <= ymax THEN CALL PlotPoint(x, y) NEXT gx END SUB SUB DrawGrid fudge = 3.33 'minimum 3 lines, maximum 30, normally about 10 xstep = 10 ^ INT(LOG(fudge * (xmax - xmin)) / LOG(10) - 1) ystep = 10 ^ INT(LOG(fudge * (ymax - ymin)) / LOG(10) - 1) xstep1 = xstep * SGN(xmin): IF xstep1 = 0 THEN xstep1 = xstep xstep2 = xstep * SGN(xmax): IF xstep2 = 0 THEN xstep2 = xstep ystep1 = ystep * SGN(ymin): IF ystep1 = 0 THEN ystep1 = ystep ystep2 = ystep * SGN(ymax): IF ystep2 = 0 THEN ystep2 = ystep FOR x = 0 TO xmin STEP xstep1 gx = gxmin + gxdiff * (x - xmin) / (xmax - xmin) IF gx >= gxmin AND gx <= gxmax THEN LINE (gx, gymin)-(gx, gymax), gridcolour NEXT x FOR x = 0 TO xmax STEP xstep2 gx = gxmin + gxdiff * (x - xmin) / (xmax - xmin) IF gx >= gxmin AND gx <= gxmax THEN LINE (gx, gymin)-(gx, gymax), gridcolour NEXT x FOR y = 0 TO ymin STEP ystep1 gy = gymin + gydiff * (y - ymin) / (ymax - ymin) IF gy >= gymin AND gy <= gymax THEN LINE (gxmin, gymax - gy)-(gxmax, gymax - gy), gridcolour NEXT y FOR y = 0 TO ymax STEP ystep2 gy = gymin + gydiff * (y - ymin) / (ymax - ymin) IF gy >= gymin AND gy <= gymax THEN LINE (gxmin, gymax - gy)-(gxmax, gymax - gy), gridcolour NEXT y END SUB SUB DrawPoint (xc, yc, colour, s) LINE (xc - s, gymax - yc - s)-(xc + s, gymax - yc + s), colour, BF END SUB FUNCTION fc (x, a, b, g, h, f) fc = func(func(a, x, g), func(b, x, h), f) END FUNCTION FUNCTION fstring$ (c$, x$, f) SELECT CASE f CASE 1: fstring$ = c$ CASE 2: fstring$ = c$ + " + " + x$ CASE 3: fstring$ = c$ + " - " + x$ CASE 4: fstring$ = c$ + " * " + x$ CASE 5: fstring$ = c$ + " / " + x$ CASE 6: fstring$ = x$ + " ^ " + c$ CASE 7: fstring$ = c$ + " + " + x$ + " ^ 2" CASE 8: fstring$ = "SIN(2 * Pi * " + c$ + " * " + x$ + ")" CASE 9: fstring$ = "COS(2 * Pi * " + c$ + " * " + x$ + ")" CASE 10: fstring$ = "TAN(2 * Pi * " + c$ + " * " + x$ + ")" CASE 11: fstring$ = "ATN(" + c$ + " * " + x$ + ")" CASE 12: fstring$ = "LOG(" + c$ + " * " + x$ + ")" CASE 13: fstring$ = "EXP(" + c$ + " * " + x$ + ")" CASE 14: fstring$ = "SQR(" + c$ + " * " + x$ + ")" CASE 15: fstring$ = "INT(" + c$ + " * " + x$ + ")" CASE 16: fstring$ = "ABS(" + c$ + " * " + x$ + ")" CASE 17: fstring$ = "SGN(" + c$ + " * " + x$ + ")" CASE 18: fstring$ = x$ + " MOD " + c$ CASE ELSE: PRINT "Program error: function "; f; "does not exist." END SELECT END FUNCTION FUNCTION func (c, x, f) func = 0 SELECT CASE f CASE 1: func = c CASE 2: func = c + x CASE 3: func = c - x CASE 4: func = c * x CASE 5: IF x <> 0 THEN func = c / x CASE 6: func = x ^ c CASE 7: func = c + x * x CASE 8: func = SIN(2 * Pi * c * x) CASE 9: func = COS(2 * Pi * c * x) CASE 10: func = TAN(2 * Pi * c * x) CASE 11: func = ATN(c * x) CASE 12: IF c * x > 0 THEN func = LOG(c * x) CASE 13: func = EXP(c * x) CASE 14: IF c * x >= 0 THEN func = SQR(c * x) CASE 15: func = INT(c * x) CASE 16: func = ABS(c * x) CASE 17: func = SGN(c * x) CASE 18: IF CINT(c) <> 0 THEN func = x MOD c CASE ELSE: PRINT "Program error: function "; f; "does not exist." END SELECT END FUNCTION FUNCTION GetConstant (c, const$) LOCATE 1, 1 PRINT "Change a Constant" PRINT "The constant "; const$; " now has the value "; c; "." INPUT "Type a number and press Enter"; c GetConstant = c END FUNCTION FUNCTION GetFunction (f, f$, c$, x$) DO LOCATE 1, 1 PRINT "Functions" FOR i = 1 TO nfunctions PRINT i, f$; " = "; fstring$(c$, x$, i) NEXT i PRINT "The function "; f$; " is now"; f, f$; " = "; fstring$(c$, x$, f) PRINT "Type a number from 1 to"; nfunctions; "and press Enter"; INPUT newn IF newn < 1 OR newn > nfunctions THEN PRINT "Sorry, that number is not ok. Please try again." LOOP WHILE newn < 1 OR newn > nfunctions GetFunction = INT(newn) END FUNCTION FUNCTION GetLimit (lim, l$) DO gc = GetConstant(lim, l$) IF l$ = "xmin" THEN xmin = gc ELSEIF l$ = "xmax" THEN xmax = gc ELSEIF l$ = "ymin" THEN ymin = gc ELSEIF l$ = "ymax" THEN ymax = gc END IF IF xmin >= xmax OR ymin >= ymax THEN PRINT "Sorry, the min must be less than the max. Please try again." LOOP WHILE xmin >= xmax OR ymin >= ymax GetLimit = gc END FUNCTION SUB PlotPoint (x, y) gx = gxmin + gxdiff * (x - xmin) / (xmax - xmin) gy = gymin + gydiff * (y - ymin) / (ymax - ymin) CALL DrawPoint(gx, gy, pointcolour, pointsize) END SUB SUB PrintInfo ndisp = 28 DIM disp$(ndisp) IF autofit = 1 THEN af$ = "off" ELSE af$ = "on" disp$(1) = "Graphing Program" disp$(2) = "" disp$(3) = "Keys Actions" disp$(4) = "---- -------" disp$(5) = "a,b Change constants" disp$(6) = "c Random change" disp$(7) = "d Change point density" disp$(8) = "f,g,h Change functions" disp$(9) = "m Menu of sample graphs" disp$(10) = "p Change point size" disp$(11) = "r Reset all variables" disp$(12) = "s,t Change xmin and xmax" disp$(13) = "u,v Change ymin and ymax" disp$(14) = "y Switch " + af$ + " autofit of y" disp$(15) = "Esc Exit the program" disp$(16) = "" disp$(17) = "a = " + STR$(a) disp$(18) = "b = " + STR$(b) disp$(19) = "g = " + fstring$("a", "x", g) disp$(20) = " = " + fstring$(STR$(a), "x", g) disp$(21) = "h = " + fstring$("b", "x", h) disp$(22) = " = " + fstring$(STR$(b), "x", h) disp$(23) = "s = xmin = " + STR$(xmin) disp$(24) = "t = xmax = " + STR$(xmax) disp$(25) = " xstep = " + STR$(xstep) disp$(26) = "u = ymin = " + STR$(ymin) disp$(27) = "v = ymax = " + STR$(ymax) disp$(28) = " ystep = " + STR$(ystep) FOR i = 1 TO ndisp LOCATE i, xloc PRINT disp$(i) NEXT i LOCATE yloc, 1 PRINT "f = "; fstring$("g", "h", f) LOCATE yloc + 1, 1 PRINT " = "; fstring$("(" + fstring$("a", "x", g) + ")", "(" + fstring$("b", "x", h) + ")", f) LOCATE yloc + 2, 1 PRINT " = "; fstring$("(" + fstring$(STR$(a), "x", g) + ")", "(" + fstring$(STR$(b), "x", h) + ")", f) END SUB SUB RandomChange SELECT CASE INT(RND * 5) CASE 0: f = RandomFunction CASE 1: g = RandomFunction CASE 2: h = RandomFunction CASE 3: a = RandomReal CASE 4: b = RandomReal END SELECT END SUB FUNCTION RandomFunction DO x = INT(RND * nfunctions + 1) LOOP WHILE x = 6 OR x = 13 RandomFunction = x END FUNCTION FUNCTION RandomReal RandomReal = (2 * INT(RND * 2) - 1) * INT(RND * 10) * 10 ^ (INT(RND * 2) - 1) END FUNCTION SUB ResetVariables xmin = -5: xmax = 5: xstep = 1 ymin = -5: ymax = 5: ystep = 1 gxstep = 1: pointsize = 1 a = 1: b = 1: f = 4: g = 1: h = 1 autofit = -1 END SUB SUB SamplesMenu nsamples = 15 DIM desc$(nsamples) desc$(1) = "Line with gradient 1" desc$(2) = "Line with gradient 2" desc$(3) = "Line with gradient 0.5" desc$(4) = "Line with gradient -1" desc$(5) = "Line with gradient 1 and y-intercept 1" desc$(6) = "Parabola (Square)" desc$(7) = "Hyperbola (Reciprocal)" desc$(8) = "Sine Wave" desc$(9) = "Cosine Wave" desc$(10) = "Tangent" desc$(11) = "Logarithm" desc$(12) = "Exponential" desc$(13) = "Square Root" desc$(14) = "Cube" desc$(15) = "Square Wave" DO LOCATE 1, 1 PRINT "Sample Graphs" FOR i = 1 TO nsamples PRINT i; " "; desc$(i) NEXT i PRINT "Type a number from 1 to"; nsamples; "and press Enter"; INPUT s IF s < 1 OR s > nsamples THEN PRINT "Sorry, that number is not ok. Please try again." LOOP WHILE s < 1 OR s > nsamples SELECT CASE s CASE 1: f = 2: g = 1: h = 4: a = 0: b = 1 CASE 2: f = 2: g = 1: h = 4: a = 0: b = 2 CASE 3: f = 2: g = 1: h = 4: a = 0: b = .5 CASE 4: f = 2: g = 1: h = 4: a = 0: b = -1 CASE 5: f = 2: g = 1: h = 4: a = 1: b = 1 CASE 6: f = 7: g = 1: h = 3: a = 1: b = 2 CASE 7: f = 1: g = 5: h = 1: a = 1: b = 0 CASE 8: f = 4: g = 1: h = 8: a = 1: b = 1 CASE 9: f = 4: g = 1: h = 9: a = 1: b = 1 CASE 10: f = 4: g = 1: h = 10: a = 1: b = .25 CASE 11: f = 4: g = 1: h = 12: a = 1: b = 1 CASE 12: f = 1: g = 13: h = 1: a = 1: b = 0 CASE 13: f = 1: g = 14: h = 1: a = 1: b = 0 CASE 14: f = 1: g = 6: h = 1: a = 3: b = 0 CASE 15: f = 17: g = 8: h = 1: a = 1: b = 1 CASE ELSE: PRINT "Error in Samplesmenu: nsamples="; nsamples END SELECT END SUB