A small function plotter in MMBasic

' a function plotting program. + and - zoom in and out. Esc exits the program.
' still work in progress. I'm keeping the code short so not to create errors in editor.
CLS RGB(white)
rd=RGB(red)
bl=RGB(blue)
gy=RGB(gray)
wh=RGB(white)
'define constants
gs=10 'grid steps
oX=160 'x of origin
oY=160 'y of origin
'sc=0.1 'original scaling
'set up display with a white background
Color bl, RGB(white)
'ask the user for a function expression
Print "Function:"
Input funcExpression$
Print "Scaling:"
Input scale$
sc=Val(scale$)
'main loop
'draw the grid
Do
For x=0 To 320 Step gs
Line x, 0, x, 319, , gy
Next x
For y=0 To 320 Step gs
Line 0, y, 319, y, , gy
Next y
'draw x and y axes
Line oX, 0, oX, 319, 2, rd
Line 0, oY, 319, oY, 2, rd
For x=-160 To 159
'evaluate the function for x
y=Eval(funcExpression$)*sc
'scale down the y to fit the screen
nY=oY-y
Line oX+x, nY, oX+x+1, nY, 4, bl
Next x
'second loop
Do
'check for key press
key$=Inkey$
If key$="+" Then
sc=sc*0.9
CLS wh
Exit Do 'exit second loop
ElseIf key$="-" Then
sc=sc*1.1
CLS wh
Exit Do 'exit second loop
End If
'exit the first loop if ESC is pressed
If key$=Chr$(27) Then
Exit Do
End If
Loop
Pause 100
'exit the first loop if ESC is pressed
If key$=Chr$(27) Then
Exit Do
End If
Loop
'restore screen to original
CLS RGB(black), RGB(green)
3 Likes

Thanks for posting that. I love it when people post their code as it allows everybody to see other ideas in different ways of thinking.

Being a long time since I programmed in basic and that was on an HP 71B and a few sharp and Casio calculators.

2 Likes


Hi all!
I’ve got some little bit of free time today and did an upgrade (together with GPT ) to my function plotter app.
What is changed:

  • support for up to 3 functions
  • correct the scaling of the grid and function graph
  • added panning
  • added numbering on the grid
  • added a point which display the x and y coordinates of the function
  • corrected errors like dividing by zero, etc.
  • display the function text on the screen
    Keyboard commands:
  • Panning with UP, DOWN, LEFT, RIGHT arrows
  • Return to the Function and Scaling input with BACK
  • Move the cursor with A, W, X, D
  • Zooming with + and -
  • Exit the app with ESC
    Some things to consider is the syntax when inputting the function. -X² will be seen by MMBasic as (-x)². It should be written as -(X²) instead. As well, there is no possibility for moving the cursor when writting the function so any correction should be done with BACK. Other issues might be discovered later, still improving.
    Feel free to give me your feedback, change the code or use it as you please. I don’t own it, WE are.
bl=RGB(black)
rd=RGB(red)
gn=RGB(green)
bu=RGB(blue)
wh=RGB(white)
cy=RGB(cyan)
mg=RGB(magenta)
yl=RGB(yellow)

Dim f$(3)
Dim c(3)
c(1)=cy
c(2)=mg
c(3)=yl

Do
 CLS bl
 ox=160
 oy=160
 dx=0
 dy=0
 gs=10
 cursorXval=0
 cursorYval=0
 Color gn,bl

 Print "How many functions (1-3)?"
 Input n
 If n<1 Then n=1
 If n>3 Then n=3

 For i=1 To n
  Print "Function ";i;":"
  Input f$(i)
 Next

 Print "Scaling:"
 Input s$
 sc=Val(s$)

 CLS bl

 restart=0

 Do
  sp=gs/sc

  ' Compute pixel position from graph coordinates
  cx=Int(ox+dx+(cursorXval/sc))
  cyr=Int(oy+dy-(cursorYval/sc))

  startX=Int((-ox-dx)/sp)-1
  endX=Int((319-ox-dx)/sp)+1
  For i=startX To endX
   xg=ox+i*sp+dx
   Line Int(xg),0,Int(xg),319,,bu
  Next

  startY=Int((-oy-dy)/sp)-1
  endY=Int((319-oy-dy)/sp)+1
  For i=startY To endY
   yg=oy+i*sp+dy
   Line 0,Int(yg),319,Int(yg),,bu
  Next

  For i=startX To endX
   xg=ox+i*sp+dx
   If xg>=0 And xg<=319 Then
    Text Int(xg),310,Str$(i*gs)
   EndIf
  Next

  For i=startY To endY
   yg=oy+i*sp+dy
   If yg>=0 And yg<=319 Then
    Text 0,Int(yg),Str$(-i*gs)
   EndIf
  Next

  Line ox+dx,0,ox+dx,319,2,rd
  Line 0,oy+dy,319,oy+dy,2,rd

  ' Function labels
  For fn=1 To n
   Color c(fn),bl
   Text 180,fn*10-10,f$(fn)
  Next
  Color gn,bl

  ' Plot functions
  For fn=1 To n
   col=c(fn)
   For px=-160 To 159
    xv=px*sc
    x=xv
    On Error Ignore
    yv=Eval(f$(fn))
    On Error Abort
    py=oy+dy-(yv/sc)
    x1=Int(ox+dx+px)
    x2=x1+1
    y=Int(py)
    If y>=0 And y<=319 Then
     Line x1,y,x2,y,4,col
    EndIf
   Next
  Next

  ' Draw cursor lines
  Line cx,0,cx,319,,wh
  Line 0,cyr,319,cyr,,wh

  ' Check if cursor is on any function
  found=0
  For fn=1 To n
   x=cursorXval
   On Error Ignore
   yv=Eval(f$(fn))
   On Error Abort
   diff=Abs(yv-cursorYval)
   If diff<sc*0.5 Then
    txtX=Int(cx+5)
    txtY=Int(cyr-10)
    Color c(fn),bl
    Text txtX,txtY,"X=" + Str$(cursorXval)
    Text txtX,txtY+10,"Y=" + Str$(yv)
    Color gn,bl
    found=1
    Exit For
   EndIf
  Next

  Do
   k$=Inkey$
   If k$="+" Then
    sc=sc*0.9
    CLS bl
    Exit Do
   EndIf
   If k$="-" Then
    sc=sc*1.1
    CLS bl
    Exit Do
   EndIf
   If k$=Chr$(130) Then
    dx=dx+10
    CLS bl
    Exit Do
   EndIf
   If k$=Chr$(131) Then
    dx=dx-10
    CLS bl
    Exit Do
   EndIf
   If k$=Chr$(128) Then
    dy=dy+10
    CLS bl
    Exit Do
   EndIf
   If k$=Chr$(129) Then
    dy=dy-10
    CLS bl
    Exit Do
   EndIf
   If k$=Chr$(8) Then
    restart=1
    CLS bl
    Exit Do
   EndIf
   If k$="a" Or k$="A" Then
    cursorXval=cursorXval-sc
    CLS bl
    Exit Do
   EndIf
   If k$="d" Or k$="D" Then
    cursorXval=cursorXval+sc
    CLS bl
    Exit Do
   EndIf
   If k$="w" Or k$="W" Then
    cursorYval=cursorYval+sc
    CLS bl
    Exit Do
   EndIf
   If k$="x" Or k$="X" Then
    cursorYval=cursorYval-sc
    CLS bl
    Exit Do
   EndIf
   If k$=Chr$(27) Then
    CLS bl,gn
    End
   EndIf
  Loop

  Pause 100
  If restart=1 Then Exit Do
 Loop
Loop

CLS bl,gn

5 Likes

I’ve already find an issue with my code: for scaling over 1, the grid and associated text is stacked together making it unreadable. Probably I’ll ditch this option altogether and remain only with + or - zooming, or rescale the grid and associated numbering proportional with the scaling, so instead of 10, 20, 30… we’ll have 50, 100, 150… I’ll play with it and fix these problems and others that I might stumble upon on the next version.

2 Likes

You can change the Pause to 10 and the refresh rate will be faster. You can as well long press UP, DOWN, LEFT, RIGHT or A, W, X, D and it will go faster, but don’t exaggerate since you’ll have to wait until the app takes the next command.

2 Likes