'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 Vec2
' position vector d
AS Vec2
' direction vector n
AS Vec2
' 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
IF x
= 0 THEN ' starting positions bl
(x
).p.y
= INT(ytable
* .5) bl
(x
).p.x
= INT(xtable
* .75) 'DO
' bl(x).p.y = INT((RND(1) * (ytable - (bsiz * 2))) + bsiz)
' bl(x).p.x = INT((RND(1) * (xtable - (bsiz * 2))) + bsiz)
' t = 0
' FOR y = 0 TO x - 1
' d = ((bl(x).p.x - bl(y).p.x) ^ 2 + (bl(x).p.y - bl(y).p.y) ^ 2) ^ .5
' IF d < bsiz * 2 THEN t = -1
' NEXT y
'LOOP UNTIL NOT t
MakeBalls
RackEmUp
'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
bl
(0).d.x
= (bl
(0).p.x
- _MOUSEX) * 0.05 bl
(0).d.y
= (bl
(0).p.y
- _MOUSEY) * 0.05 'VecNorm bl(0).d: VecMult bl(0).d, 40
'slope of target line
LINE (bl
(0).p.x
, bl
(0).p.y
)-(pathx
* 1000, pathy
* 1000), Blue
'LINE (bl(0).p.x, bl(0).p.y)-(-(_MOUSEX - bl(0).p.x) + bl(0).p.x, -(_MOUSEY - bl(0).p.y) + bl(0).p.y), Blue
'd = SQR(((bl(0).p.x - _MOUSEX) * 0.05) * ((bl(0).p.x - _MOUSEX) * 0.05) + ((bl(0).p.y - _MOUSEY) * 0.05) * ((bl(0).p.y - _MOUSEY) * 0.05))
'_PRINTSTRING (xtable + 4, ytable - 20), STR$(d), a&
'SLEEP
' 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
'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 = PythXY(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
'Using a variation of the collision routine from CTVector.bas
'but the damn thing isn't working as envisioned...
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
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 = PythXY(orthox, bl(x).p): voy = PythXY(orthoy, bl(x).p)
strikeorth.x = -strike.y: strikeorth.y = strike.x
strikeorth = strike
strikeorth.x = strike.y: strikeorth.y = -strike.x
'// 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 * PythXY(origin, bl(var).d)
VecAdd bl(x).d, strike, 1
'do the same with var using balance of energy
VecMult strikeorth, 0.99 * dotback * PythXY(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
'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
striker = bl(var).d: VecNorm striker
IF x
<> var
THEN ' another ball? d
= _HYPOT(bl
(var
).p.x
- bl
(x
).p.x
, bl
(var
).p.y
- bl
(x
).p.y
) ''here's the crunchy part
'we must find the actual impact point, rather than the overlap at iteration point
'maybe that will fix the sticking
strike.x = bl(x).p.x - bl(var).p.x ' get strike angle unit vector
strike.y = bl(x).p.y - bl(var).p.y
VecNorm strike
'striker = bl(var).d: VecNorm striker ' get striker unit vector
'strikee = bl(x).d: VecNorm strikee ' get strikee unit vector
''dot product the striker and strikee
'dot = striker.x * strikee.x + striker.y * strikee.y
'dotback = 1 - dot
'VecMult strike, dot * _HYPOT(bl(var).d.x, bl(var).d.y)
'VecAdd bl(x).d, strike, 1
'a temporary test
bl(x).d.x = strike.x * (.8 * bl(var).d.x)
bl(x).d.y = strike.y * (.8 * bl(var).d.y)
bl(var).d.x = -strike.y * (.2 * bl(var).d.y)
bl(var).d.y = -strike.x * (.2 * bl(var).d.x)
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
'Use to find distance between two 2D points
'Also calculate speed/magnitude of updated vectors
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
'multiply vector by scalar value
vec.x = vec.x * multiplier
vec.y = vec.y * multiplier
SUB VecNorm
(var
AS Vec2
)
'convert var to unit vector
m
= SQR(var.x
* var.x
+ var.y
* var.y
) var.x = var.x / m
var.y = var.y / m