-   
- 'ball colors 1 yellow 2 blue 3 red 4 purple 5 orange 6 green 7 maroon 8 black 
- '9 yellow/s 10 blue/s 11 red/s 12 purple/s 13 orange/s 14 green/s 15 maroon/s 
-   
-   
-     sunk  AS _BYTE '                                             has ball been sunk true/false
-     p  AS-  V2  '                                                 position vector
-     d  AS-  V2  '                                                 direction vector
-     n  AS-  V2  '                                                 normalized direction vector
-   
- origin.x = 0: origin.y = 0 
-   
- 'Set the table size 
-   
- bsiz  = INT(((- xtable  / 118.1102) * 2.375) / 2) '                 size balls to table
- bsiz2 = bsiz * 2 
-   
-   
- MakeBalls 
- RackEmUp 
- bl (0)- .p.y  = INT(- ytable  * .5) '                                  position the cue
- bl (0)- .p.x  = INT(- xtable  * .75)
-   
-   
- 'set up the table 
-     LINE (- x ,-  x )-(- xtable  --  x ,-  ytable  --  x ),-  Black ,-  B 
 
-     FCirc xtable * .75, ytable * .5, 5, Gray, Gray 
-     FCirc xtable * .75, ytable * .5, 2, White, White 
-         VecAdd bl(x).p, bl(x).d, 1 
-         VecMult bl(x).d, .99 
-         ColCheck x 
-   
-     ms = MBS% 
-         bl (0)- .d.x  = (- bl (0)- .p.x  - _MOUSEX) * 0.05
-         bl (0)- .d.y  = (- bl (0)- .p.y  - _MOUSEY) * 0.05
-         BallStop 
-         bl (0)- .p.y  = INT(- ytable  * .5)
-         bl (0)- .p.x  = INT(- xtable  * .75)
-         RackEmUp 
-     'slope of target line 
-     LINE (- bl (0)- .p.x ,-  bl (0)- .p.y )-(- pathx  * 1000,-  pathy  * 1000),-  Blue 
 
-   
-   
- '                                                               DATA SECTION 
- hue: 
- DATA 4294967295,4294967040,4278190335,4294901760,4286578816,4294944000,4278222848,4286578688 
- DATA 4278190080,4294967040,4278190335,4294901760,4286578816,4294944000,4278222848,4286578688 
-   
- start: 
- DATA 1,2,15,14,8,3,4,6,11,13,12,7,9,10,5,0 
-   
- SUB-  B2BCollision  (- ball1  AS-  ball ,-  ball2  AS-  ball )
 
-   
-     DIM AS-  V2 un ,-  ut ,-  ncomp1 ,-  ncomp2 ,-  tcomp1 ,-  tcomp2 
 
-     un = ball2.p: VecAdd un, ball1.p, -1: VecNorm un '          establish unit normal 
-     ut.x = -un.y: ut.y = un.x '                                 establish unit tangent 
-     bnci1 = VecDot(un, ball1.d) '                               ball 1 normal component of input velocity 
-     bnci2 = VecDot(un, ball2.d) '                               ball 2 normal component of input velocity 
-     btci1 = VecDot(ut, ball1.d) '                               ball 1 tangent component of input velocity 
-     btci2 = VecDot(ut, ball2.d) '                               ball 2 tangent component of input velocity 
-   
-     bncx1 = bnci2 '                                             compute normal component of ball 1 exit velocity 
-     bncx2 = bnci1 '                                             compute normal component of ball 2 exit velocity 
-   
-     ncomp1 = un: VecMult ncomp1, bncx1 '                        unit normal exit vector x normal component of exit vector ball1 
-     tcomp1 = ut: VecMult tcomp1, btci1 '                        unit tangent exit vector x tangent component of exit vector 
-     ncomp2 = un: VecMult ncomp2, bncx2 '                        same for ball2, unit normal... 
-     tcomp2 = ut: VecMult tcomp2, btci2 '                        same for ball2, unit tangent... 
-   
-     ball1.d = ncomp1: VecAdd ball1.d, tcomp1, 1 '               add normal and tangent exit vectors 
-     ball2.d = ncomp2: VecAdd ball2.d, tcomp2, 1 '               add normal and tangent exit vectors 
-   
-   
-   
-   
-         bl(x).d = origin 
-   
-   
-   
-   
-     'check for ball in displacement radius 
-     disp  = SQR(- bl (- var )- .d.x  *-  bl (- var )- .d.x  +-  bl (- var )- .d.y  *-  bl (- var )- .d.y ) 'vector magnitude for this iteration
-         IF-  x  <>-  var  THEN '                                      won't collide with self so skip self check
 
-             IF NOT-  bl (- var )- .sunk  THEN '                          if ball not already out of play
 
-                 dist = PyT(bl(var).p, bl(x).p) '                calculate distance between var and x 
-                 IF-  dist  --  bsiz2  <-  disp  THEN '                   if ball x is within reach of magnitude
 
-                     'check to see if there is an impact point-  Ray trace routine 
-                     'DIM strike AS V2 
-                     'DIM strikeorth AS V2 
-                     'DIM striker AS V2 
-                     'DIM strikee AS V2 
-                     'DIM orthox AS V2 
-                     'DIM orthoy AS V2 
-   
-                     'Using a variation of the collision routine from CTVector.bas 
-                     'but the damn thing isn't working as envisioned... well it didn't work there either. 
-                     dx = bl(var).p.x - bl(x).p.x 
-                     dy = bl(var).p.y - bl(x).p.y 
-                     A## = (bl(var).d.x * bl(var).d.x) + (bl(var).d.y * bl(var).d.y) 'displacement range 
-                     B## = 2 * bl(var).d.x * dx + 2 * bl(var).d.y * dy 
-                         C## = (bl(x).p.x * bl(x).p.x) + (bl(x).p.y * bl(x).p.y) + (bl(var).p.x * bl(var).p.x)_ 
-                              + (bl(var).p.y * bl(var).p.y) + -2 * (bl(x).p.x * bl(var).p.x + bl(x).p.y * bl(var).p.y) - (bsiz2 * bsiz2) 
-                     disabc## = (B## * B##) - 4 * A## * C## 
-                     IF-  disabc##  <= 0 THEN 'let's make this <=, since a tangent brush by would ideally not move the ball
 
-                         t## = (-B## - ((B## * B##) - 4 * A## * C##) ^ .5) / (2 * A##) 'near intersect quadratic gives percentage of displacement to contact 
-                         neari.x = bl(var).p.x + t## * bl(var).d.x: neari.y = bl(var).p.y + t## * bl(var).d.y 'contact point 
-                         'now that we have a contact point, we can proceed to deflect the displacements of var and x 
-   
-                         'Not sure yet how to get impact points but we can replace the following with SUB B2BCollision 
-                         'bl(var).p = neari 
-                         ''// get strike angle unit vector 
-                         'strike.x = bl(x).p.x - neari.x: strike.y = bl(x).p.y - neari.y 
-                         ''// get the two orthogonal vectors to strike 
-                         'orthox.x = -strike.y: orthox.y = strike.x 
-                         'orthoy.x = strike.y: orthoy.y = -strike.x 
-                         ''// add orthogonals to impact point 
-                         'VecAdd orthox, neari, 1: VecAdd orthoy, neari, 1 
-                         ''// add present var displacement to ortho's 
-                         'VecAdd orthox, bl(var).d, 1: VecAdd orthoy, bl(var).d, 1 
-                         ''// check distances and compare, using farthest one for striker's new vector 
-                         'vox = PyT(orthox, bl(x).p): voy = PyT(orthoy, bl(x).p) 
-                         'IF vox > voy THEN 
-                         '    strikeorth.x = -strike.y: strikeorth.y = strike.x 
-                         'ELSEIF vox = voy THEN 
-                         '    strikeorth = strike 
-                         'ELSE 
-                         '    strikeorth.x = strike.y: strikeorth.y = -strike.x 
-                         'END IF 
-                         ''// normalize strike vectors 
-                         'VecNorm strike: VecNorm strikeorth 
-   
-   
-                         'striker = bl(var).d: VecNorm striker '                  get striker unit vector 
-                         'strikee = bl(x).d: VecNorm strikee '                    get strikee unit vector 
-                         'dot = striker.x * strike.x + striker.y * strike.y '     apply to struck balls displacement magnitude along strike 
-                         'dotback = 1 - dot '                                     apply to striking balls displacement along orthogonal of strike 
-   
-                         ''get proportion of energy transfer and add it to existing vector of unit x 
-                         'VecMult strike, 0.99 * dot * PyT(origin, bl(var).d) 
-                         'VecAdd bl(x).d, strike, 1 
-                         ''do the same with var using balance of energy 
-                         'VecMult strikeorth, 0.99 * dotback * PyT(origin, bl(var).d) 
-                         ''VecAdd bl(var).d, strikeorth, 1 
-                         'bl(var).d = strikeorth 
-                         ''bl(var).d.x = -bl(var).d.x: bl(var).d.y = -bl(var).d.y 
-                         B2BCollision bl(var), bl(x) 
-   
-     'wall bounces 
-     IF-  bl (- var )- .p.x  <-  bsiz  OR-  bl (- var )- .p.x  >-  xtable  --  bsiz  THEN
 
-         bl(var).d.x = -bl(var).d.x 
-         IF-  bl (- var )- .p.x  <-  bsiz  THEN '                            if beyond left edge
 
-             bl(var).p.y = bl(var).p.y - (bl(var).d.y * ((bl(var).p.x - bsiz) / bl(var).d.x)) 
-             bl(var).p.x = bsiz 
-         IF-  bl (- var )- .p.x  >-  xtable  --  bsiz  THEN '                   if beyond right edge
 
-             bl(var).p.y = bl(var).p.y - (bl(var).d.y * ((bl(var).p.x - xtable + bsiz) / bl(var).d.x)) 
-             bl(var).p.x = xtable - bsiz 
-     IF-  bl (- var )- .p.y  <-  bsiz  OR-  bl (- var )- .p.y  >-  ytable  --  bsiz  THEN
 
-         bl(var).d.y = -bl(var).d.y 
-         IF-  bl (- var )- .p.y  <-  bsiz  THEN '                            if beyond top edge
 
-             bl(var).p.x = bl(var).p.x - (bl(var).d.x * ((bl(var).p.y - bsiz) / bl(var).d.y)) 
-             bl(var).p.y = bsiz 
-         IF-  bl (- var )- .p.y  >-  ytable  --  bsiz  THEN '                   if beyond bottom edge
 
-             bl(var).p.x = bl(var).p.x - (bl(var).d.x * ((bl(var).p.y - ytable + bsiz) / bl(var).d.y)) 
-             bl(var).p.y = ytable - bsiz 
-   
-   
-   
-   
-     RError = -R 
-     X = R 
-     Y = 0 
-     LINE (- CX  --  X ,-  CY )-(- CX  +-  X ,-  CY ),-  C ,-  BF 
 
-         RError = RError + Y * 2 + 1 
-                 LINE (- CX  --  Y ,-  CY  --  X )-(- CX  +-  Y ,-  CY  --  X ),-  C2 ,-  BF  'these two need white here for 9-15 balls
 
-                 LINE (- CX  --  Y ,-  CY  +-  X )-(- CX  +-  Y ,-  CY  +-  X ),-  C2 ,-  BF 
 
-             X = X - 1 
-             RError = RError - X * 2 
-         Y = Y + 1 
-         LINE (- CX  --  X ,-  CY  --  Y )-(- CX  +-  X ,-  CY  --  Y ),-  C ,-  BF 
 
-         LINE (- CX  --  X ,-  CY  +-  Y )-(- CX  +-  X ,-  CY  +-  Y ),-  C ,-  BF 
 
-   
-   
-   
-   
-   
-   
-   
-   
-         'make ball images here 
-         bnum (- x ) = _NEWIMAGE(- bsiz  * 2 + 4,-  bsiz  * 2 + 4, 32)
-             'Solids or stripes 
-             FCirc  INT(_WIDTH(- bnum (- x )) / 2), INT(_HEIGHT(- bnum (- x )) / 2),-  bsiz  - 5,-  White ,-  White  'number circle
-   
-   
-   
- FUNCTION-  MBS%  'Mouse Button Status  Author: Steve McNeill
 
-     CONST-  ClickLimit##  = 0.2 'Less than 1/4th of a second to down, up a key to count as a CLICK.
 
-     '                          Down longer counts as a HOLD event. 
-     SHARED-  Mouse_StartX ,-  Mouse_StartY ,-  Mouse_EndX ,-  Mouse_EndY 
 
-     WHILE _MOUSEINPUT 'Remark out this block, if mouse main input/clear is going to be handled manually in main program. 
-   
-   
-         IF _MOUSEBUTTON(1) THEN 'If a button is pressed, start the timer to see what it does (click or hold) 
-             ButtonDown  = 1- : StartTimer  = TIMER(0.01)
-             ButtonDown  = 2- : StartTimer  = TIMER(0.01)
-             ButtonDown  = 3- : StartTimer  = TIMER(0.01)
-         IF TIMER(0.01) --  StartTimer  <=-  ClickLimit  THEN 'Button was down, then up, within time limit.  It's a click
 
-                 MBS = 0: ButtonDown = 0: StartTimer = 0 
-             ELSE 'We've now started the hold event 
-                 MBS  =-  MBS  OR 32 * 2 ^-  ButtonDown 
-   
-   
-   
-     PyT  = _HYPOT(ABS(- var1.x  --  var2.x ), ABS(- var1.y  --  var2.y )) '  distances and magnitudes
-   
-   
-   
-   
-     yoff = bsiz2 + 4 
-     xoff  = SQR((- yoff  / 2) * (- yoff  / 2) +-  yoff  *-  yoff )
-   
-             bl(k).p.x = (.25 * xtable) - (xoff * (rank - 1)) 
-             bl(k).p.y = (.5 * ytable) - ((rank - 1) * (.5 * yoff)) + ((b - 1) * yoff) 
-   
-   
-   
-   
-     var.x = var.x + (var2.x * var3) '                           add (or subtract) two vectors defined by unitpoint 
-     var.y = var.y + (var2.y * var3) '                           var= base vector, var2= vector to add 
-   
-   
-   
-   
-     VecDot = var.x * var2.x + var.y * var2.y '                  get dot product of var & var2 
-   
-   
-   
-   
-     vec.x = vec.x * multiplier '                                multiply vector by scalar value 
-     vec.y = vec.y * multiplier 
-   
-   
-   
-     m  = SQR(- var.x  *-  var.x  +-  var.y  *-  var.y ) '                    convert var to unit vector
-     var.x = var.x / m 
-     var.y = var.y / m 
-   
-   
-