'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 tablebsiz2 = bsiz * 2
MakeBalls
RackEmUp
bl
(0).p.y
= INT(ytable
* .5) ' position the cuebl
(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