'Original code by OldMoses
'Additional code by Novarseg
RAD = 0
DIM vertex
(1, 1) AS V2
' mouse grabbing handles
'DIM SHARED AS V2 origin
origin.x = 0: origin.y = 0
b(0).c = Red: b(0).cn = "red"
b(1).c = Cyan: b(1).cn = "cyan"
' _SCREENMOVE 10, 10
'MAG = 4
'starting state
b(0).m.x = 0: b(0).m.y = 100 ' reds approach vector
b(0).s = PyT(origin, b(0).m)
b(1).m.x = -100: b(1).m.y = 0 ' cyans approach vector
b(1).s = PyT(origin, b(1).m)
b(0).p.x = 0: b(0).p.y = 0 ' ball position x, y
b(1).p.x = -100: b(1).p.y = 100 'ball position x, y
ms = MBS ' process mouse actions dragging endpoints
mouse.x
= map!
(_MOUSEX, 0, 599, -300, 300) mouse.y
= map!
(_MOUSEY, 0, 599, 300, -300)
ds! = PyT(vertex(x, y), mouse)
IF ds!
< ballradius
* .5 THEN i
= x: j
= y
SELECT CASE j
' grabbing impact position or start of incoming vector CASE IS = 0 ' impact position- here we use mouse as the new b(#).p b(i).p = mouse
CASE IS = 1 ' starting point- here we obtain the b(#).m mathematically b(i).m = b(i).p: VecAdd b(i).m, mouse, -1
'IF _KEYDOWN(114) THEN i = 0
'IF _KEYDOWN(99) THEN i = 1
'IF _KEYDOWN(119) THEN b(i).m.y = b(i).m.y - 1
'IF _KEYDOWN(115) THEN b(i).m.y = b(i).m.y + 1
'IF _KEYDOWN(97) THEN b(i).m.x = b(i).m.x + 1
'IF _KEYDOWN(100) THEN b(i).m.x = b(i).m.x - 1
'**************Code added by Novarseg
'Vector rotation and vector magnitude adjustment using keyboard input
f4 = 1
b(i).s = PyT(origin, b(i).m)
b
(i
).m.y
= b
(i
).s
* COS(RAD
(i
)) b
(i
).m.x
= b
(i
).s
* SIN(RAD
(i
)) i = 0
_DELAY .04 'allows enough time for keyboard buffer to accumulate characters ' so the vector rotation (fast / slow) operates properly
' there is probably a better way to do this
'IF f3 = 0 THEN I$ = "b": f3 = 1
IF I$
= "b" AND f2
= 0 THEN i
= 1: f2
= 1: c
(1) = " SELECTED": c
(0) = " ":
GOTO LL1
'cyan IF I$
= "b" AND f2
= 1 THEN i
= 0: f2
= 0: c
(0) = " SELECTED": c
(1) = " " 'red LL1:
IF I$
= "c" THEN 'increase vector magnitude mult = 1.01
VecMult b(i).m, mult
IF I$
= "v" THEN 'decrease vector magnitude div = 1.01
VecDIV b(i).m, div 'added a new sub
IF I$
= "z" THEN 'rotate vector counter clockwise
b(i).s = PyT(origin, b(i).m)
b
(i
).m.y
= b
(i
).s
* COS(RAD
(i
)) b
(i
).m.x
= b
(i
).s
* SIN(RAD
(i
))
IF I$
= "x" THEN 'rotate vector clockwise
b(i).s = PyT(origin, b(i).m)
b
(i
).m.y
= b
(i
).s
* COS(RAD
(i
)) b
(i
).m.x
= b
(i
).s
* SIN(RAD
(i
)) '**************END Code added Novarseg
'START OF COLLISION MATHEMATICS SECTION
ballradius = PyT(b(0).p, b(1).p) / 2
vertex(bn, 0) = b(bn).p ' first we establish the mouse handles for ball position
vertex(bn, 1) = b(bn).p: VecAdd vertex(bn, 1), b(bn).m, -1 ' and incoming vector starting point
'Now all the previous garbage is distilled into a single SUB call once a collision is determined
B2BCollision b(0), b(1), Nvec(), Tvec()
'END OF COLLISION MATHEMATICS SECTION
'graphic representation
LINE (grid
, 300)-(grid
, -300), c&
'Gray 'vertical lines LINE (-300, grid
)-(300, grid
), c&
' Gray 'horizontal lines
LINE (b
(1).p.x
, b
(1).p.y
)-(b
(0).p.x
, b
(0).p.y
), White
, , &B0010001000100010
'strike vector
CIRCLE (b
(dr
).p.x
, b
(dr
).p.y
), ballradius
, b
(dr
).c
, , , 1 'AR
LINE (b
(dr
).p.x
, b
(dr
).p.y
)-(b
(dr
).p.x
+ b
(dr
).m.x
, b
(dr
).p.y
+ b
(dr
).m.y
), b
(dr
).c
'incoming
'LINE (b(dr).p.x, b(dr).p.y)-(b(dr).p.x + b(dr).x.x, b(dr).p.y + b(dr).x.y), b(dr).c, , &B1111000011110000 'exit vector
LINE (b
(dr
).p.x
, b
(dr
).p.y
)-(b
(dr
).p.x
+ Nvec
(dr
).x
, b
(dr
).p.y
+ Nvec
(dr
).y
), b
(dr
).c
, , &B1111000011110000
'exit vector LINE (b
(dr
).p.x
, b
(dr
).p.y
)-(b
(dr
).p.x
+ Tvec
(dr
).x
, b
(dr
).p.y
+ Tvec
(dr
).y
), b
(dr
).c
, , &B1111000011110000
'exit vector
TEXT
(dr
) = b$
+ CHR$(13) + CHR$(10) 'NOVARSEG added this line
PUT #1, , TEXT
(0) 'NOVARSEG added this line PUT #1, , TEXT
(1) 'NOVARSEG added this line CLOSE 'NOVARSEG added this line END IF 'NOVARSEG added this line
SUB B2BCollision
(ball0
AS ball
, ball1
AS ball
, Nvec
() AS V2
, Tvec
() AS V2
)
' DIM AS V2 un, ut, ncomp1, ncomp2, tcomp1, tcomp2
DIM unDOT0
AS SINGLE 'unit normal vector "dot" pre collision heading ball0 DIM unDOT1
AS SINGLE 'unit normal vector "dot" pre collision heading ball1 DIM utDOT0
AS SINGLE 'unit tangent vector "dot" pre collision heading ball0 DIM utDOT1
AS SINGLE ' unit tangent vector "dot" pre collision heading ball1
' DIM nvec(1) AS V2
' DIM Tvec(1) AS V2
' GOSUB getUnitNormal uses ball1.p ball2.p
'calculate unit normql vector from ball positions
'ball0 = red, ball1 =cyan
un.x = ball1.p.x - ball0.p.x
un.y = ball1.p.y - ball0.p.y
MAG = (un.x ^ 2 + un.y ^ 2) ^ .5
un.x = un.x / MAG
un.y = un.y / MAG
'un = ball0.p: VecAdd un, ball1.p, -1: VecNorm un '
'un = ball1.p
'VecAdd un, ball1.p, -1
' VecNorm un ' establish unit normal
ut.x = -un.y: ut.y = un.x ' establish unit tangent
unDOT0 = un.x * ball0.m.x + un.y * ball0.m.y 'unit normal vector DOT ball vector
unDOT1 = un.x * ball1.m.x + un.y * ball1.m.y 'unit normal vector DOT ball vector
utDOT0 = ut.x * ball0.m.x + ut.y * ball0.m.y 'unit tangent vector DOT ball vector
utDOT1 = ut.x * ball1.m.x + ut.y * ball1.m.y 'unit tangent vector DOT ball vector
'bnci1 = VecDot(un, ball0.m) '
'bnci2 = VecDot(un, ball1.m) '
'btci1 = VecDot(ut, ball0.m) '
'btci2 = VecDot(ut, ball1.m) '
' bncx1 = bnci2 ' compute normal component of ball 1 exit velocity
' bncx2 = bnci1 ' compute normal component of ball 2 exit velocity
' ncomp1 = un:
VecMult2 un, unDOT0, unVec0 ' first two parameters are inputs, the 3rd is output vector
VecMult2 ut, utDOT0, utVec0 '
VecMult2 un, unDOT1, unVec1 '
VecMult2 ut, utDOT1, utVec1 '
'ncomp1 = un: VecMult ncomp1, bncx2 '
'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...
'ball0.x = ncomp1: VecAdd ball0.x, tcomp1, 1 ' add normal and tangent exit vectors
'ball1.x = ncomp2: VecAdd ball1.x, tcomp2, 1 ' add normal and tangent exit vectors
'VecAdd2 unVec1, utVec1, Nvec(1) '
'VecAdd2 unVec0, utVec0, Nvec(0) '
Nvec(0).x = unVec0.x
Nvec(0).y = unVec0.y
Nvec(1).x = unVec1.x
Nvec(1).y = unVec1.y
Tvec(1).x = -utVec0.x
Tvec(1).y = -utVec0.y
Tvec(0).x = -utVec1.x
Tvec(0).y = -utVec1.y
SUB B2B2Collision
(ball0
AS ball
, ball1
AS ball
)
' DIM AS V2 un, ut, ncomp1, ncomp2, tcomp1, tcomp2
DIM unDOT0
AS SINGLE 'unit normal vector "dot" pre collision heading ball0 DIM unDOT1
AS SINGLE 'unit normal vector "dot" pre collision heading ball1 DIM utDOT0
AS SINGLE 'unit tangent vector "dot" pre collision heading ball0 DIM utDOT1
AS SINGLE ' unit tangent vector "dot" pre collision heading ball1
' GOSUB getUnitNormal uses ball1.p ball2.p
'calculate unit normql vector from ball positions
'ball0 = red, ball1 =cyan
un.x = ball1.p.x - ball0.p.x
un.y = ball1.p.y - ball0.p.y
MAG = (un.x ^ 2 + un.y ^ 2) ^ .5
un.x = un.x / MAG
un.y = un.y / MAG
' 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, ball0.m) '
bnci2 = VecDot(un, ball1.m) '
btci1 = VecDot(ut, ball0.m) '
btci2 = VecDot(ut, ball1.m) '
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...
ball0.x = ncomp1: VecAdd ball0.x, tcomp1, 1 ' add normal and tangent exit vectors
ball1.x = ncomp2: VecAdd ball1.x, tcomp2, 1 ' add normal and tangent exit vectors
FUNCTION map!
(value!
, minRange!
, maxRange!
, newMinRange!
, newMaxRange!
)
map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!
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(var1.x
- var2.x
, var1.y
- var2.y
)
FUNCTION bPyT
(var1
AS V2
, var2
AS V2
, var3
) 'to calulate ball radius only 'var1.x = var1.x * 1.6384
bPyT
= _HYPOT((var1.x
- var2.x
) * var3
, (var1.y
- var2.y
) * var3
)
var.x = -(var.x + (var2.x * var3)) ' add vector (or a scalar multiple of) var2 to var)
var.y = var.y + (var2.y * var3) ' use var3 = -1 to subtract var2 from var
SUB VecAdd2
(var1
AS V2
, var2
AS V2
, var3
AS V2
)
'var3.x = var1.x + var2.x ' add vector (or a scalar multiple of) var2 to var)
'var3.y = var1.y + var2.y ' use var3 = -1 to subtract var2 from var
var3.x = var1.x '+ var2.x ' add vector (or a scalar multiple of) var2 to var)
var3.y = var1.y '+ var2.y ' use var3 = -1 to subtract var2 from var
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
out1.x = var1.x * var2
out1.y = var1.y * var2
vec.x = vec.x / divisor
vec.y = vec.y / divisor
m = PyT(origin, var)
var.x = 0: var.y = 0 ' vector with magnitude 0 is a zero vector
var.x = var.x / m: var.y = var.y / m ' convert var to unit vector