'Mass on Spring Resonance

'by "Dutchman" Ton Nillesen, August 2026
'See http://hyperphysics.phy-astr.gsu.edu/hbase/shm2.html
'
'===== User settings
k=40 ' spring constant in Newton per meter
m=1  ' mass in kg

'===== Presets
iPhoneTest=0  ' simulate small iPhone
DoubleQuit=0  ' to make screenshot after first quit
OPTION ANGLE RADIANS
DRAW LINECAP ROUND
SET TOOLBAR OFF
SET ORIENTATION VERTICAL
Rs=0 ! Gs=0 ! Bs=0.5 ' screen color
Rd=1 ! Gd=1 ! Bd=0 ' draw color
Rf=1 ! Gf=0 ! Bf=0 ' fill color

'===== determine frequency
' It is independent of gravity
w=SQR(k/m) ' angular frequency of oscillation

'===== Constants:
PI=3.1415926535
GOSUB Screen ' Set screen parameters
radius=rw*sw/10 'size of mass
midx=sw/2 ! midy=sh/2
margin=50 ' bottom margin
topy=rh*10 ! maxy=sh-rh*margin 'top and bottom of moving range
resty=(maxy-2*radius-topy)/2 ' length of spring in rest
swing=resty-rh*margin   ' modulation of springlength
'
'===== Main
DRAW SIZE MAX(2,radius/20)
DRAW COLOR Rd,Gd,Bd
GOSUB Controls
TIME RESET
DO
  length=resty+swing*SIN(w*TIME())
  GOSUB DrawState
UNTIL BUTTON_PRESSED("quit")
IF DoubleQuit THEN
  PAUSE 0.5
  DO ! UNTIL BUTTON_PRESSED("quit") 'wait for screenshot
ENDIF
BUTTON "quit" DELETE
SET ORIENTATION ALL
SET TOOLBAR ON
TEXT
END
'
'======== Subroutines and Functions ===========
DrawState: 'draw spring+mass
  REFRESH OFF
  GOSUB Clear
  DRAW LINE midx,0 TO midx,topy
  CALL DrawSpring(10,radius,length,midx,topy)
  DRAW LINE midx,topy+length TO midx,2*topy+length+radius
  FILL CIRCLE midx,2*topy+length+radius SIZE radius
  REFRESH
RETURN

DEF DrawSpring(turns,peak,length,startx,starty)
  dphi=turns*2*.PI/length
  phi=dphi
  DRAW TO startx,starty
  FOR n=1 TO length
    point=SIN(n*dphi)
    x=Startx+peak*point
    y=starty+n
    DRAW LINE TO x,y
    phi+=dphi
  NEXT n
  DRAW LINE TO startx,starty+length
END DEF

Screen: ' Set screen parameters
  GRAPHICS
  IF iPhoneTest THEN
    sw=320 ! sh=568
  ELSE
    sw=SCREEN_WIDTH()
    sh=SCREEN_HEIGHT()
  ENDIF
  rw=sw/768 ! rh=sh/1024
  GOSUB Clear
RETURN

Clear:
  IF iPhoneTest THEN
    FILL COLOR Rs,Gs,Bs
    FILL RECT 0,0 TO sw,sh
  ELSE
    GRAPHICS CLEAR Rs,Gs,Bs
  ENDIF
  DRAW COLOR Rd,Gd,Bd
  FILL COLOR Rf,Gf,Bf
RETURN
  
Controls:
  Freq=INT(w/Pi/2*100)/100
  Text$="Freqency: "&STR$(Freq,"##.##")&" Hz"
  Ltext=LEN(Text$)
  Fsize=SQR(rh)*20 ! Tsize=(Ltext)*Fsize*0.5
  FIELD "F" TEXT "" AT midx,sh-margin ' dummy to set "F"
  FIELD "F" FONT SIZE Fsize
  FIELD "F" TEXT Text$ AT midx-tsize/2,sh-margin
  SetQuitButton(Fsize,sw-4*Fsize,0)
RETURN

DEF SetQuitButton(fsize,x,y)
  SET BUTTONS CUSTOM
  SET BUTTONS FONT SIZE fsize
  FILL COLOR 1,0,0
  DRAW COLOR 1,1,0
  BUTTON "quit" TEXT "Quit" AT x,y 
END DEF
