
REM ****     BOUNCING BALLS IN A BOX    by smbstarv
REM ****     elementary mechanics from https://en.m.wikipedia.org/wiki/Elastic_collision
     /*   a 2-dimensional rectangle box (w * h),
     two 3-dimensional balls b1, b2, b3 (r1, r2, r3)
     with mass m1, m2, m3 ( m1=4/3*pi*r1^3*m0, m2=4/3*pi*r2^3*m0, m3=...)
     b1 moves WITH velocity v1, ANGLE a1, its centre starting from point x1,y1
     b2 moves WITH velocity v2, ANGLE a2, its centre starting from point x2,y2
     b3 ....
     */ 
     IF DEVICE_TYPE$()<>"iPad" THEN
         PRINT "for iPad only"
         STOP
     END IF
'r'
 START:
     SET ORIENTATION 2
     SET TOOLBAR OFF
     w=SCREEN_WIDTH()*.8
     h=SCREEN_HEIGHT()*.8
     OPTION ANGLE RADIANS
     pi=4*ATAN(1)
     deltime=.01                                 'animation delaytime
     
'balls
     r1=w*.09                                    'ball b1
     r2=w*.05                                    'ball b2
     r3=w*.07                                    'ball b3
     r12=r1+r2
     rr12=(r1+r2)^2
     r13=r1+r3
     rr13=(r1+r3)^2
     r23=r2+r3
     rr23=(r2+r3)^2
     
'weight
     m0=1
     m1=4/3*pi*r1^3*m0
     m2=4/3*pi*r2^3*m0
     m3=4/3*pi*r3^3*m0
     M212=2*m2/(m1+m2)
     M112=2*m1/(m1+m2)
     M313=2*m3/(m1+m3)
     M113=2*m1/(m1+m3)
     M223=2*m2/(m2+m3)
     M323=2*m3/(m2+m3)
     
'boundaries of the box
     ls=w*.1                                     'left side
     ls1=ls+r1
     ls2=ls+r2
     ls3=ls+r3
     rs=w/8*9                                    'right side
     rs1=rs-r1
     rs2=rs-r2
     rs3=rs-r3
     us=h*.1                                     'upside
     us1=us+r1
     us2=us+r2
     us3=us+r3
     DS=h/8*9                                    'downside
     ds1=DS-r1
     ds2=DS-r2
     ds3=DS-r3
     
'initial position and velocity-coordinates
     x1=w*.3
     y1=h*.7
     x2=w*.6
     y2=h*.7
     x3=w*.5
     y3=h*.7
     v1=0
     v2=10  
     v3=5
     a1=0
     a2=2
     a3=1
     v1x=v1*COS(a1)
     v1y=v1*SIN(a1)
     v2x=v2*COS(a2)
     v2y=v2*SIN(a2)
     v3x=v3*COS(a3)
     v3y=v3*SIN(a3)
     
'screen
     GRAPHICS
     GRAPHICS CLEAR 0,0,0
     DRAW LINE ls,us TO rs,us
     DRAW LINE ls,us TO ls,DS
     DRAW LINE rs,us TO rs,DS
     DRAW LINE rs,DS TO ls,DS
     
     OPTION SPRITE POS CENTRAL
     SPRITE "b1" BEGIN 2*r1,2*r1
     FILL COLOR 1,0,0
     FILL CIRCLE r1,r1 SIZE r1
     SPRITE END
     SPRITE "b1" AT x1,y1
     SPRITE "b1" SHOW
     
     SPRITE "b2" BEGIN 2*r2,2*r2
     FILL COLOR 0,1,0
     FILL CIRCLE r2,r2 SIZE r2
     SPRITE END
     SPRITE "b2" AT x2,y2
     SPRITE "b2" SHOW
     
     SPRITE "b3" BEGIN 2*r3,2*r3
     FILL COLOR 0,0,1
     FILL CIRCLE r3,r3 SIZE r3
     SPRITE END
     SPRITE "b3" AT x3,y3
     SPRITE "b3" SHOW
     
     SPRITE "b1" DELAY deltime
     SPRITE "b1" DX v1x DY v1y
     SPRITE "b1" LOOP
     
     SPRITE "b2" DELAY deltime
     SPRITE "b2" DX v2x DY v2y
     SPRITE "b2" LOOP
     
     SPRITE "b3" DELAY deltime
     SPRITE "b3" DX v3x DY v3y
     SPRITE "b3" LOOP
'b'
 l1:
     GET SPRITE "b1" POS x,y
     IF x>rs1  THEN                              'b1 bounces right side
         v1x=-v1x
         SPRITE "b1" DX v1x
         WHILE x>rs1
             GET SPRITE "b1" POS x,y
         END WHILE
     ENDIF
     
     IF x<ls1 THEN                               'b1 bounces left side
         v1x=-v1x
         SPRITE "b1" DX v1x
         WHILE x<ls1
             GET SPRITE "b1" POS x,y
         END WHILE
     ENDIF
     
     IF y>ds1 THEN                               'b1 bounces lower side
         v1y=-v1y
         SPRITE "b1" DY v1y
         WHILE y>ds1
             GET SPRITE "b1" POS x,y
         END WHILE
     ENDIF
     
     IF y<us1 THEN                               'b1 bounces upper side
         v1y=-v1y
         SPRITE "b1" DY v1y
         WHILE y<us1
             GET SPRITE "b1" POS x,y
         END WHILE
     ENDIF
     
     
     GET SPRITE "b2" POS x,y
     IF x>rs2 THEN                               'b2 bounces right side
         v2x=-v2x
         SPRITE "b2" DX v2x
         WHILE x>rs2
             GET SPRITE "b2" POS x,y
         END WHILE
     ENDIF
     
     IF x<ls2 THEN                               'b2 bounces left side
         v2x=-v2x
         SPRITE "b2" DX v2x
         WHILE x<ls2
             GET SPRITE "b2" POS x,y
         END WHILE
     ENDIF
     
     
     IF y>ds2 THEN                               'b2 bounces lower side
         v2y=-v2y
         SPRITE "b2" DY v2y
         WHILE y>ds2
             GET SPRITE "b2" POS x,y
         END WHILE
     ENDIF
     
     
     IF y<us2 THEN                               'b2 bounces upper side
         v2y=-v2y
         SPRITE "b2" DY v2y
         WHILE y<us2
             GET SPRITE "b2" POS x,y
         END WHILE
     ENDIF
     
          
     GET SPRITE "b3" POS x,y
     IF x>rs3 THEN                               'b3 bounces right side
         v3x=-v3x
         SPRITE "b3" DX v3x
         WHILE x>rs3
             GET SPRITE "b3" POS x,y
         END WHILE
     ENDIF
     
     IF x<ls3 THEN                               'b3 bounces left side
         v3x=-v3x
         SPRITE "b3" DX v3x
         WHILE x<ls3
             GET SPRITE "b3" POS x,y
         END WHILE
     ENDIF
     
     
     IF y>ds3 THEN                               'b3 bounces lower side
         v3y=-v3y
         SPRITE "b3" DY v3y
         WHILE y>ds3
             GET SPRITE "b3" POS x,y
         END WHILE
     ENDIF
     
     
     IF y<us3 THEN                               'b3 bounces upper side
         v3y=-v3y
         SPRITE "b3" DY v3y
         WHILE y<us3
             GET SPRITE "b3" POS x,y
         END WHILE
     ENDIF
''   error ?     
     IF x1<ls OR x2<ls OR x3<ls OR y1<us OR y2<us OR y3<us THEN GOTO error'out of bounds error
     IF x1>rs OR x2>rs OR x3>rs OR y1>DS OR y2>DS OR y3>DS THEN GOTO error'out of bounds error
     
'y'
     GET SPRITE "b1" POS x1,y1
     GET SPRITE "b2" POS x2,y2
     dist=(x2-x1)^2+(y2-y1)^2 
     IF dist<rr12 THEN                           'b1 and b2 are bouncing
         SPRITE "b1" STOP
         SPRITE "b2" STOP
'calculating angles and velocities after collision
         x12=x1-x2
         y12=y1-y2
         INtterm=((v1x-v2x)*(x1-x2)+(v1y-v2y)*(y1-y2))/dist
         
         u1x=v1x-M212*INtterm*x12                   'x coord of b1 after collision
         u1y=v1y-M212*INtterm*y12                   'y coord of b1 after collision
         
         u2x=v2x+M112*INtterm*x12
         u2y=v2y+M112*INtterm*y12
         
         v1x=u1x
         v1y=u1y
         v2x=u2x
         v2y=u2y
         v1=SQR(u1x^2+u1y^2)
         v2=SQR(u2x^2+u2y^2)
         SPRITE "b1"  DX u1x DY u1y
         SPRITE "b2"  DX u2x DY u2y
         SPRITE "b1" PLAY
         SPRITE "b2" PLAY
         
         WHILE dist<rr12                         ' wait until disjunct
             GET SPRITE "b1" POS x1,y1
             GET SPRITE "b2" POS x2,y2
             dist=(x2-x1)^2+(y2-y1)^2
         END WHILE
         
     END IF
     
     GET SPRITE "b1" POS x1,y1
     GET SPRITE "b3" POS x3,y3 
     dist=(x3-x1)^2+(y3-y1)^2
     IF dist<rr13 THEN                           'b1 and b3 are bouncing
         SPRITE "b1" STOP
         SPRITE "b3" STOP
'calculating angles and velocities after collision
         x13=x1-x3
         y13=y1-y3
         INtterm=((v1x-v3x)*(x1-x3)+(v1y-v3y)*(y1-y3))/dist
         
         u1x=v1x-M313*INtterm*x13                   'x coord of b1 after collision
         u1y=v1y-M313*INtterm*y13                   'y coord of b1 after collision
         
         u3x=v3x+M113*INtterm*x13
         u3y=v3y+M113*INtterm*y13
         
         v1x=u1x
         v1y=u1y
         v3x=u3x
         v3y=u3y
         v1=SQR(u1x^2+u1y^2)
         v3=SQR(u3x^2+u3y^2)
         SPRITE "b1"  DX u1x DY u1y
         SPRITE "b3"  DX u3x DY u3y
         SPRITE "b1" PLAY
         SPRITE "b3" PLAY
         
         WHILE dist<rr13                         ' wait until disjunct
             GET SPRITE "b1" POS x1,y1
             GET SPRITE "b3" POS x3,y3
             dist=(x3-x1)^2+(y3-y1)^2
         END WHILE
         
     END IF
     
     GET SPRITE "b2" POS x2,y2
     GET SPRITE "b3" POS x3,y3
     dist=(x2-x3)^2+(y2-y3)^2
     IF dist<rr23 THEN                           'b2 and b3 are bouncing
         SPRITE "b2" STOP
         SPRITE "b3" STOP
'calculating angles and velocities after collision
         x23=x2-x3
         y23=y2-y3
         INtterm=((v2x-v3x)*(x2-x3)+(v2y-v3y)*(y2-y3))/dist
         
         u2x=v2x-M323*INtterm*x23                   'x coord of b1 after collision
         u2y=v2y-M323*INtterm*y23                 'y coord of b1 after collision
         
         u3x=v3x+M223*INtterm*x23
         u3y=v3y+M223*INtterm*y23
         
         v2x=u2x
         v2y=u2y
         v3x=u3x
         v3y=u3y
         v2=SQR(u2x^2+u2y^2)
         v3=SQR(u3x^2+u3y^2)
         SPRITE "b2"  DX u2x DY u2y
         SPRITE "b3"  DX u3x DY u3y
         SPRITE "b2" PLAY
         SPRITE "b3" PLAY
         
         WHILE dist<rr23                        ' wait until disjunct
             GET SPRITE "b2" POS x2,y2
             GET SPRITE "b3" POS x3,y3
             dist=(x3-x2)^2+(y3-y2)^2
         END WHILE
         
     END IF
     
'c'
     tch=TOUCH_X(0)                              'to quit, touch screen
     IF tch>0 THEN
         GRAPHICS CLEAR 0,0,0
         SPRITES DELETE
         TEXT
         SET TOOLBAR ON
         STOP
     END IF
     
     GOTO l1
     
error:
     BEEP
     GOTO START
     END
     
