Rem * Title : simple line collision
Rem * Author : trager
Rem * Date : 9-feb-2003
set text opaque
rem draw a wall to test collision against
wall_start_x# = 100
wall_start_y# = 100
wall_end_y# = 350
wall_end_x# = 350
line wall_start_x#, wall_start_y#, wall_end_x#, wall_end_y#
rem stage 0 asks for start position
rem stage 1 ask for end position
rem stage 2 calculates the point of collision
text 0,0,"Click the start position of the balls path"
stage = 0
ink rgb(255,0,0), rgb(0,0,0)
do
rem the user defines the start and end postion of balls path using_
rem mouse clicks in the desired location
if stage = 0 and mouseclick() =1
rem get the ball start position when user clicks the mouse for the first time
ball_start_x# = mousex()
ball_start_y# = mousey()
dot ball_start_x#, ball_start_y#
stage = 1
text 0,0," "
text 0,0,"Click the end position of the balls path"
wait 500
else
if stage = 1 and mouseclick() = 1
rem get the ball end position when the user clicks the mouse for the secound time
ball_end_x# = mousex()
ball_end_y# = mousey()
dot ball_end_x#, ball_end_y#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
circle ball_start_x#, ball_start_y#, 8
circle ball_end_x#, ball_end_y#, 8
rem get the speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
remstart
this part of the code increase the length of the line by adding 8 to the end of each line
this ensures that the collision is tested to the edge of the ball
rather than just to the centre of the balls resting position
remend
if ball_xv# <> 0 and ball_yv# <>0
rem we can predict the values of yR# and xR# acurately if the ball fails to
rem move along one of the axis.
R# = sqrt(ball_xv#*ball_xv# + ball_yv#*ball_yv#)
yR# = ball_yv#/R#
xR# = ball_xv#/R#
else
yR# = 0
xR# = 1
if ball_xv# = 0 and ball_yv# <> 0
rem if the ball has vertically but not horizontally
yR# = 1
xR# = 0
endif
endif
rem once we calculated how much to add on to each end of the line we do so
ball_end_y# = ball_end_y# + yR# * 8.0
ball_end_x# = ball_end_x# + xR# * 8.0
ball_start_y# = ball_start_y# - yR# * 8.0
ball_start_x# = ball_start_x# - xR# * 8.0
rem and then add a nice green line to show the line we will be testing
rem notice the green line goes from the back of the start ball to
rem the front of the finish ball
ink rgb(0,255,0),rgb(0,0,0)
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
rem get the new speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
stage = 2
text 0,0," "
text 0,0,"Click left mouse button to get location of collision"
wait 500
else
if stage = 2 and mouseclick() = 1
rem on the third mouse click the program calculates the position of a collision
gosub show_collision
wait 500
endif
endif
endif
sync
loop
show_collision:
remstart
this part of the code finds the collision point between the wall
and the balls path and then draws a circle around it
remend
rem get the x and y difference from start to end of wall
rem the x length and y length if you like
wall_xv# = wall_end_x# - wall_start_x#
wall_yv# = wall_end_y# - wall_start_y#
rem now understanding how this next part works is not important
rem just know that this is the collision test basically it calcs s and t
rem if s and t are between 0 and 1 then there has been a collision
s# = ((0-ball_yv#) * (ball_start_x#-wall_start_x#) + ball_xv#*(ball_start_y#-wall_start_y#)) / ((0-wall_xv#)*ball_yv# + ball_xv#*wall_yv#)
t# = (wall_xv# * (ball_start_y#-wall_start_y#) - wall_yv# * (ball_start_x#-wall_start_x#)) / ((0-wall_xv#)*ball_yv# + ball_xv#*wall_yv#)
if (s# >=0 and s# <= 1) and (t# >= 0 and t# <=1)
rem now we have established that there has been a collision we must calculate
rem where it is, again its not important that you understand this
rem just as long as you know what it does
rem once the collision point is calculated we draw a circle around it
rem to show where it is
collision_x# = ball_start_x# + (t# * ball_xv#)
collision_y# = ball_start_y# + (t# * ball_yv#)
ink rgb(0,0,255),rgb(0,0,0)
circle collision_x#, collision_y#, 8
else
text 100,100, "There is no collision"
endif
return
Rem * Title : simple line collision
Rem * Author : trager
Rem * Date : 9-feb-2003
set text opaque
rem draw a wall to test collision against
wall_start_x# = 100
wall_start_y# = 100
wall_end_y# = 350
wall_end_x# =350
line wall_start_x#, wall_start_y#, wall_end_x#, wall_end_y#
rem stage 0 asks for start position
rem stage 1 ask for end position
rem stage 2 calculates the point of collision
text 0,0,"Click the start position of the balls path"
stage = 0
ink rgb(255,0,0), rgb(0,0,0)
do
rem the user defines the start and end postion of balls path using_
rem mouse clicks in the desired location
if stage = 0 and mouseclick() =1
rem get the ball start position when user clicks the mouse for the first time
ball_start_x# = mousex()
ball_start_y# = mousey()
dot ball_start_x#, ball_start_y#
stage = 1
text 0,0," "
text 0,0,"Click the end position of the balls path"
wait 500
else
if stage = 1 and mouseclick() = 1
rem get the ball end position when the user clicks the mouse for the secound time
ball_end_x# = mousex()
ball_end_y# = mousey()
dot ball_end_x#, ball_end_y#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
circle ball_start_x#, ball_start_y#, 8
circle ball_end_x#, ball_end_y#, 8
rem get the speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
remstart
this part of the code increase the length of the line by adding 8 to the end of each line
this ensures that the collision is tested to the edge of the ball
rather than just to the centre of the balls resting position
remend
if ball_xv# <> 0 and ball_yv# <>0
rem we can predict the values of yR# and xR# acurately if the ball fails to
rem move along one of the axis.
R# = sqrt(ball_xv#*ball_xv# + ball_yv#*ball_yv#)
yR# = ball_yv#/R#
xR# = ball_xv#/R#
else
yR# = 0
xR# = 1
if ball_xv# = 0 and ball_yv# <> 0
rem if the ball has vertically but not horizontally
yR# = 1
xR# = 0
endif
endif
rem once we calculated how much to add on to each end of the line we do so
ball_end_y# = ball_end_y# + yR# * 8.0
ball_end_x# = ball_end_x# + xR# * 8.0
ball_start_y# = ball_start_y# - yR# * 8.0
ball_start_x# = ball_start_x# - xR# * 8.0
rem and then add a nice green line to show the line we will be testing
rem notice the green line goes from the back of the start ball to
rem the front of the finish ball
ink rgb(0,255,0),rgb(0,0,0)
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
rem get the new speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
stage = 2
text 0,0," "
text 0,0,"Click left mouse button to get location of collision"
wait 500
else
if stage = 2 and mouseclick() = 1
rem on the third mouse click the program calculates the position of a collision
gosub show_collision
wait 500
endif
endif
endif
sync
loop
show_collision:
remstart
this part of the code finds the collision point between the wall
and the balls path and then draws a circle around it
remend
rem get the x and y difference from start to end of wall
rem the x length and y length if you like
wall_xv# = wall_end_x# - wall_start_x#
wall_yv# = wall_end_y# - wall_start_y#
rem now understanding how this next part works is not important
rem just know that this is the collision test basically it calcs s and t
rem if s and t are between 0 and 1 then there has been a collision
s# = ((0-ball_yv#) * (ball_start_x#-wall_start_x#) + ball_xv#*(ball_start_y#-wall_start_y#)) / ((0-wall_xv#)*ball_yv# + ball_xv#*wall_yv#)
t# = (wall_xv# * (ball_start_y#-wall_start_y#) - wall_yv# * (ball_start_x#-wall_start_x#)) / ((0-wall_xv#)*ball_yv# + ball_xv#*wall_yv#)
if (s# >=0 and s# <= 1) and (t# >= 0 and t# <=1)
rem only runs this part if a collision occured
gosub calc_ball_pos
ink rgb(0,0,255),rgb(0,0,0)
circle collision_x#, collision_y#, 8
else
text 100,100, "There is no collision"
endif
return
calc_ball_pos:
rem now we have established that there has been a collision we must calculate
rem where it is, again its not important that you understand this
rem just as long as you know what it does
rem once the collision point is calculated we draw a circle around it
rem to show where it is
rem this places the ball in the exact position of collision
rem so that the edge of the ball is touching the wall and not the ball centre
ra# =(atanfull(ball_xv#,ball_yv#) - atanfull(wall_xv#,wall_yv#))
ras# = sqrt((1-cos(2*ra#))/2)
rem use a ball radius of 10 to allow for any discrepancies
cb# = 10 *(1-ras#) / ras#
ab# = sqrt(100 + cb#*cb#)
collision_y# = (ball_start_y# + (t# * ball_yv#)) - yR# * ab#
collision_x# = (ball_start_x# + (t# * ball_xv#)) - xR# * ab#
return
Rem * Title : simple line collision
Rem * Author : trager
Rem * Date : 9-feb-2003
set text opaque
rem draw a wall to test collision against
wall_start_x# = 100
wall_start_y# = 100
wall_end_y# = 350
wall_end_x# =350
line wall_start_x#, wall_start_y#, wall_end_x#, wall_end_y#
rem stage 0 asks for start position
rem stage 1 ask for end position
rem stage 2 calculates the point of collision
text 0,0,"Click the start position of the balls path"
stage = 0
ink rgb(255,0,0), rgb(0,0,0)
do
rem the user defines the start and end postion of balls path using_
rem mouse clicks in the desired location
if stage = 0 and mouseclick() =1
rem get the ball start position when user clicks the mouse for the first time
ball_start_x# = mousex()
ball_start_y# = mousey()
dot ball_start_x#, ball_start_y#
stage = 1
text 0,0," "
text 0,0,"Click the end position of the balls path"
wait 500
else
if stage = 1 and mouseclick() = 1
rem get the ball end position when the user clicks the mouse for the secound time
ball_end_x# = mousex()
ball_end_y# = mousey()
dot ball_end_x#, ball_end_y#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
circle ball_start_x#, ball_start_y#, 8
circle ball_end_x#, ball_end_y#, 8
rem get the speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
remstart
this part of the code increase the length of the line by adding 8 to the end of each line
this ensures that the collision is tested to the edge of the ball
rather than just to the centre of the balls resting position
remend
if ball_xv# <> 0 and ball_yv# <>0
rem we can predict the values of yR# and xR# acurately if the ball fails to
rem move along one of the axis.
R# = sqrt(ball_xv#*ball_xv# + ball_yv#*ball_yv#)
yR# = ball_yv#/R#
xR# = ball_xv#/R#
else
yR# = 0
xR# = 1
if ball_xv# = 0 and ball_yv# <> 0
rem if the ball has vertically but not horizontally
yR# = 1
xR# = 0
endif
endif
rem once we calculated how much to add on to each end of the line we do so
oEx# = ball_end_x#
oEy# = ball_end_y#
ball_end_y# = ball_end_y# + yR# * 8.0
ball_end_x# = ball_end_x# + xR# * 8.0
ball_start_y# = ball_start_y# - yR# * 8.0
ball_start_x# = ball_start_x# - xR# * 8.0
rem and then add a nice green line to show the line we will be testing
rem notice the green line goes from the back of the start ball to
rem the front of the finish ball
ink rgb(0,255,0),rgb(0,0,0)
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
rem get the new speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
stage = 2
text 0,0," "
text 0,0,"Click left mouse button to get location of collision"
wait 500
else
if stage = 2 and mouseclick() = 1
rem on the third mouse click the program calculates the position of a collision
gosub show_collision
wait 500
endif
endif
endif
sync
loop
show_collision:
remstart
this part of the code finds the collision point between the wall
and the balls path and then draws a circle around it
remend
rem get the x and y difference from start to end of wall
rem the x length and y length if you like
wall_xv# = wall_end_x# - wall_start_x#
wall_yv# = wall_end_y# - wall_start_y#
rem now understanding how this next part works is not important
rem just know that this is the collision test basically it calcs s and t
rem if s and t are between 0 and 1 then there has been a collision
s# = ((0-ball_yv#) * (ball_start_x#-wall_start_x#) + ball_xv#*(ball_start_y#-wall_start_y#)) / ((0-wall_xv#)*ball_yv# + ball_xv#*wall_yv#)
t# = (wall_xv# * (ball_start_y#-wall_start_y#) - wall_yv# * (ball_start_x#-wall_start_x#)) / ((0-wall_xv#)*ball_yv# + ball_xv#*wall_yv#)
if (s# >=0 and s# <= 1) and (t# >= 0 and t# <=1)
rem only runs this part if a collision occured
gosub calc_ball_pos
else
text 100,100, "There is no collision"
endif
return
calc_ball_pos:
rem now we have established that there has been a collision we must calculate
rem where it is, again its not important that you understand this
rem just as long as you know what it does
rem once the collision point is calculated we draw a circle around it
rem to show where it is
rem this places the ball in the exact position of collision
rem so that the edge of the ball is touching the wall and not the ball centre
ra# =(atanfull(ball_xv#,ball_yv#) - atanfull(wall_xv#,wall_yv#))
ras# = sqrt((1-cos(2*ra#))/2)
rem use a ball radius of 10 to allow for any discrepancies
cb# = 10 *(1-ras#) / ras#
ab# = sqrt(100 + cb#*cb#)
collision_y# = (ball_start_y# + (t# * ball_yv#)) - yR# * ab#
collision_x# = (ball_start_x# + (t# * ball_xv#)) - xR# * ab#
gosub calc_return
return
calc_return:
remstart
right then this little mess calculates the return velocities
of the ball after it has hit the wall, pretty aint it
again you dont have to understand how it works only recognise the wall and ball
variables
the blue circle now shows the final resting position of the ball after a colision
this means that the ball travels the exact distance dictate by its speed
so the calculation performs a rebound befor the next frame
the blue line is velocity vector of the next frame.
oEx# and oEy# are to new variables that store the old_end coordinates of the ball
ie the acutall point you click with the second mouse click before adding the green
line
remend
nPx# = 0-wall_yv#
nPy# = wall_xv#
wall_length# = sqrt(nPx#*nPx# + nPy#*nPy#)
rem normalise Perpendicular
nPx# = nPx#/wall_length#
nPy# = nPy#/wall_length#
rem get N of ball
Nx# = 0-(ball_xv#*nPx# + ball_yv#*nPy#)*nPx#
Ny# = 0-(ball_xv#*nPx# + ball_yv#*nPy#)*nPy#
rem calculate remainding distance for ball to travel in this frame
rx# = ball_xv#/(oEx#-collision_x#)
ry# = ball_yv#/(oEy#-collision_y#)
rem compute ball velocities
ball_xv#= 2*Nx#+ball_xv#
ball_yv#= 2*Ny#+ball_yv#
rem position ball in final position of frame
ball_start_x# = collision_x#+ball_xv#/rx#
ball_start_y# = collision_y#+ball_yv#/ry#
ink rgb(0,0,255),rgb(0,0,0)
circle ball_start_x#, ball_start_y#, 8
rem and show the new return vector
ball_end_x# = ball_start_x# + ball_xv#
ball_end_y# = ball_start_y# + ball_yv#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
return
Rem * Title : simple line collision
Rem * Author : trager
Rem * Date : 9-feb-2003
set text opaque
rem initialise the wall characteristics
dim wall#(1,9)
start_x = 0
start_y = 1
end_x = 2
end_y = 3
xv = 4
yv= 5
angle = 6
nPx = 7
nPy = 8
wall#(1,start_x) = 100
wall#(1,start_y) = 100
wall#(1,end_x) = 350
wall#(1,end_y) = 350
rem get the x and y difference from start to end of wall
rem the x length and y length if you like
wall#(1,xv) = wall#(1,end_x) - wall#(1,start_x)
wall#(1,yv) = wall#(1,end_y) - wall#(1,start_y)
rem the angle of the wall
wall#(1,angle) = atanfull(wall#(1,xv),wall#(1,yv))
wall#(1,nPx) = 0-wall#(1,yv)
wall#(1,nPy) = wall#(1,xv)
wall_length# = sqrt(wall#(1,nPx)*wall#(1,nPx) + wall#(1,nPy)*wall#(1,nPy))
rem normalise Perpendicular
wall#(1,nPx) = wall#(1,nPx)/wall_length#
wall#(1,nPy) = wall#(1,nPy)/wall_length#
rem draw a wall to test collision against
line wall#(1,start_x), wall#(1,start_y), wall#(1,end_x), wall#(1,end_y)
rem stage 0 asks for start position
rem stage 1 ask for end position
rem stage 2 calculates the point of collision
text 0,0,"Click the start position of the balls path"
stage = 0
ink rgb(255,0,0), rgb(0,0,0)
do
rem the user defines the start and end postion of balls path using_
rem mouse clicks in the desired location
if stage = 0 and mouseclick() =1
rem get the ball start position when user clicks the mouse for the first time
ball_start_x# = mousex()
ball_start_y# = mousey()
dot ball_start_x#, ball_start_y#
stage = 1
text 0,0," "
text 0,0,"Click the end position of the balls path"
wait 500
else
if stage = 1 and mouseclick() = 1
rem get the ball end position when the user clicks the mouse for the secound time
ball_end_x# = mousex()
ball_end_y# = mousey()
dot ball_end_x#, ball_end_y#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
circle ball_start_x#, ball_start_y#, 8
circle ball_end_x#, ball_end_y#, 8
rem get the speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
remstart
this part of the code increase the length of the line by adding 8 to the end of each line
this ensures that the collision is tested to the edge of the ball
rather than just to the centre of the balls resting position
remend
if ball_xv# <> 0 and ball_yv# <>0
rem we can predict the values of yR# and xR# acurately if the ball fails to
rem move along one of the axis.
R# = sqrt(ball_xv#*ball_xv# + ball_yv#*ball_yv#)
yR# = ball_yv#/R#
xR# = ball_xv#/R#
else
if ball_xv# = 0 and ball_yv# <> 0
rem if the ball has vertically but not horizontally
if ball_start_y# <= ball_end_y#
yR# = 1
xR# = 0
else
yR# = -1
xR# = 0
endif
else
if ball_start_x# <= ball_end_x#
yR# = 0
xR# = 1
else
yR#= 0
xR#=-1
endif
endif
endif
rem once we calculated how much to add on to each end of the line we do so
oEx# = ball_end_x#
oEy# = ball_end_y#
ball_end_y# = ball_end_y# + yR# * 8.0
ball_end_x# = ball_end_x# + xR# * 8.0
ball_start_y# = ball_start_y# - yR# * 8.0
ball_start_x# = ball_start_x# - xR# * 8.0
rem and then add a nice green line to show the line we will be testing
rem notice the green line goes from the back of the start ball to
rem the front of the finish ball
ink rgb(0,255,0),rgb(0,0,0)
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
rem get the new speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
stage = 2
text 0,0," "
text 0,0,"Click left mouse button to get location of collision"
wait 500
else
if stage = 2 and mouseclick() = 1
rem on the third mouse click the program calculates the position of a collision
gosub show_collision
wait 500
end
endif
endif
endif
sync
loop
show_collision:
remstart
this part of the code finds the collision point between the wall
and the balls path and then draws a circle around it
remend
rem now understanding how this next part works is not important
rem just know that this is the collision test basically it calcs s and t
rem if s and t are between 0 and 1 then there has been a collision
s# = ((0-ball_yv#) * (ball_start_x#-wall#(1,start_x)) + ball_xv#*(ball_start_y#-wall#(1,start_y))) / ((0-wall#(1,xv))*ball_yv# + ball_xv#*wall#(1,yv))
t# = (wall#(1,xv) * (ball_start_y#-wall#(1,start_y)) - wall#(1,yv)* (ball_start_x#-wall#(1,start_x))) / ((0-wall#(1,xv))*ball_yv# + ball_xv#*wall#(1,yv))
if (s# >=0 and s# <= 1) and (t# >= 0 and t# <=1)
rem only runs this part if a collision occured
gosub calc_ball_pos
else
text 100,100, "There is no collision"
endif
return
calc_ball_pos:
rem now we have established that there has been a collision we must calculate
rem where it is, again its not important that you understand this
rem just as long as you know what it does
rem once the collision point is calculated we draw a circle around it
rem to show where it is
rem this places the ball in the exact position of collision
rem so that the edge of the ball is touching the wall and not the ball centre
ra# =(atanfull(ball_xv#,ball_yv#) - wall#(1,angle))
ras# = sqrt((1-cos(2*ra#))/2)
rem use a ball radius of 10 to allow for any discrepancies
cb# = 10 *(1-ras#) / ras#
ab# = sqrt(100 + cb#*cb#)
collision_y# = (ball_start_y# + (t# * ball_yv#)) - yR# * ab#
collision_x# = (ball_start_x# + (t# * ball_xv#)) - xR# * ab#
gosub calc_return
return
calc_return:
remstart
right then this little mess calculates the return velocities
of the ball after it has hit the wall, pretty aint it
again you dont have to understand how it works only recognise the wall and ball
variables
the blue circle now shows the final resting position of the ball after a colision
this means that the ball travels the exact distance dictate by its speed
so the calculation performs a rebound befor the next frame
the blue line is velocity vector of the next frame.
oEx# and oEy# are to new variables that store the old_end coordinates of the ball
ie the acutall point you click with the second mouse click before adding the green
line
remend
rem get N of ball
mulit# = 0-ball_xv#*wall#(1,nPx)+ ball_yv#*wall#(1,nPy)
Nx# = mulit#*wall#(1,nPx)
Ny# = mulit#*wall#(1,nPy)
rem calculate remainding distance for ball to travel in this frame
rx# = ball_xv#/(oEx#-collision_x#)
ry# = ball_yv#/(oEy#-collision_y#)
rem compute ball velocities
ball_xv#= 2*Nx#+ball_xv#
ball_yv#= 2*Ny#+ball_yv#
rem position ball in final position of frame
ball_start_x# = collision_x#+ball_xv#/rx#
ball_start_y# = collision_y#+ball_yv#/ry#
ink rgb(0,0,255),rgb(0,0,0)
circle ball_start_x#, ball_start_y#, 8
rem and show the new return vector
ball_end_x# = ball_start_x# + ball_xv#
ball_end_y# = ball_start_y# + ball_yv#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
return
Rem * Title : simple line collision
Rem * Author : trager
Rem * Date : 9-feb-2003
set text opaque
rem initialise the wall characteristics
dim wall#(2,9)
start_x = 0
start_y = 1
end_x = 2
end_y = 3
xv = 4
yv= 5
angle = 6
nPx = 7
nPy = 8
wall#(1,start_x) = 100
wall#(1,start_y) = 100
wall#(1,end_x) = 350
wall#(1,end_y) = 350
rem and wall 2
wall#(2,start_x) = 100
wall#(2,start_y) = 230
wall#(2,end_x) = 350
wall#(2,end_y) = 230
for lp = 1 to 2
rem get the x and y difference from start to end of wall
rem the x length and y length if you like
wall#(lp,xv) = wall#(lp,end_x) - wall#(lp,start_x)
wall#(lp,yv) = wall#(lp,end_y) - wall#(lp,start_y)
rem the angle of the wall
wall#(lp,angle) = atanfull(wall#(lp,xv),wall#(lp,yv))
wall#(lp,nPx) = 0-wall#(lp,yv)
wall#(lp,nPy) = wall#(lp,xv)
wall_length# = sqrt(wall#(lp,nPx)*wall#(lp,nPx) + wall#(lp,nPy)*wall#(lp,nPy))
rem normalise Perpendicular
wall#(lp,nPx) = wall#(lp,nPx)/wall_length#
wall#(lp,nPy) = wall#(lp,nPy)/wall_length#
rem draw a wall to test collision against
line wall#(lp,start_x), wall#(lp,start_y), wall#(lp,end_x), wall#(lp,end_y)
next lp
rem stage 0 asks for start position
rem stage 1 ask for end position
rem stage 2 calculates the point of collision
text 0,0,"Click the start position of the balls path"
stage = 0
ink rgb(255,0,0), rgb(0,0,0)
do
rem the user defines the start and end postion of balls path using_
rem mouse clicks in the desired location
if stage = 0 and mouseclick() =1
rem get the ball start position when user clicks the mouse for the first time
ball_start_x# = mousex()
ball_start_y# = mousey()
dot ball_start_x#, ball_start_y#
stage = 1
text 0,0," "
text 0,0,"Click the end position of the balls path"
wait 500
else
if stage = 1 and mouseclick() = 1
rem get the ball end position when the user clicks the mouse for the secound time
ball_end_x# = mousex()
ball_end_y# = mousey()
dot ball_end_x#, ball_end_y#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
circle ball_start_x#, ball_start_y#, 8
circle ball_end_x#, ball_end_y#, 8
rem get the speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
remstart
this part of the code increase the length of the line by adding 8 to the end of each line
this ensures that the collision is tested to the edge of the ball
rather than just to the centre of the balls resting position
remend
if ball_xv# <> 0 and ball_yv# <>0
rem we can predict the values of yR# and xR# acurately if the ball fails to
rem move along one of the axis.
R# = sqrt(ball_xv#*ball_xv# + ball_yv#*ball_yv#)
yR# = ball_yv#/R#
xR# = ball_xv#/R#
else
if ball_xv# = 0 and ball_yv# <> 0
rem if the ball has vertically but not horizontally
if ball_start_y# <= ball_end_y#
yR# = 1
xR# = 0
else
yR# = -1
xR# = 0
endif
else
if ball_start_x# <= ball_end_x#
yR# = 0
xR# = 1
else
yR#= 0
xR#=-1
endif
endif
endif
rem once we calculated how much to add on to each end of the line we do so
oEx# = ball_end_x#
oEy# = ball_end_y#
ball_end_y# = ball_end_y# + yR# * 8.0
ball_end_x# = ball_end_x# + xR# * 8.0
ball_start_y# = ball_start_y# - yR# * 8.0
ball_start_x# = ball_start_x# - xR# * 8.0
rem and then add a nice green line to show the line we will be testing
rem notice the green line goes from the back of the start ball to
rem the front of the finish ball
ink rgb(0,255,0),rgb(0,0,0)
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
rem get the new speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
stage = 2
text 0,0," "
text 0,0,"Click left mouse button to get location of collision"
wait 500
else
if stage = 2 and mouseclick() = 1
rem on the third mouse click the program calculates the position of a collision
collision = 0
for lp = 1 to 2
gosub show_collision
if collision = 1 then exit
next lp
wait 500
end
endif
endif
endif
sync
loop
show_collision:
remstart
this part of the code finds the collision point between the wall
and the balls path and then draws a circle around it
remend
rem now understanding how this next part works is not important
rem just know that this is the collision test basically it calcs s and t
rem if s and t are between 0 and 1 then there has been a collision
s# = ((0-ball_yv#) * (ball_start_x#-wall#(lp,start_x)) + ball_xv#*(ball_start_y#-wall#(lp,start_y))) / ((0-wall#(lp,xv))*ball_yv# + ball_xv#*wall#(lp,yv))
t# = (wall#(lp,xv) * (ball_start_y#-wall#(lp,start_y)) - wall#(lp,yv)* (ball_start_x#-wall#(lp,start_x))) / ((0-wall#(lp,xv))*ball_yv# + ball_xv#*wall#(lp,yv))
if (s# >=0 and s# <= 1) and (t# >= 0 and t# <=1)
rem only runs this part if a collision occured
if ball_xv# = 0 then ball_xv# = 0.001
if ball_yv# = 0 then ball_yv# = 0.001
gosub calc_ball_pos
collision = 1
endif
return
calc_ball_pos:
rem now we have established that there has been a collision we must calculate
rem where it is, again its not important that you understand this
rem just as long as you know what it does
rem once the collision point is calculated we draw a circle around it
rem to show where it is
rem this places the ball in the exact position of collision
rem so that the edge of the ball is touching the wall and not the ball centre
ra# =(atanfull(ball_xv#,ball_yv#) - wall#(lp,angle))
ras# = sqrt((1-cos(2*ra#))/2)
rem use a ball radius of 10 to allow for any discrepancies
cb# = 10 *(1-ras#) / ras#
ab# = sqrt(100 + cb#*cb#)
collision_y# = (ball_start_y# + (t# * ball_yv#)) - yR# * ab#
collision_x# = (ball_start_x# + (t# * ball_xv#)) - xR# * ab#
gosub calc_return
return
calc_return:
remstart
right then this little mess calculates the return velocities
of the ball after it has hit the wall, pretty aint it
again you dont have to understand how it works only recognise the wall and ball
variables
the blue circle now shows the final resting position of the ball after a colision
this means that the ball travels the exact distance dictate by its speed
so the calculation performs a rebound befor the next frame
the blue line is velocity vector of the next frame.
oEx# and oEy# are to new variables that store the old_end coordinates of the ball
ie the acutall point you click with the second mouse click before adding the green
line
remend
rem get N of ball
mulit# = 0-ball_xv#*wall#(lp,nPx)+ ball_yv#*wall#(lp,nPy)
Nx# = mulit#*wall#(lp,nPx)
Ny# = mulit#*wall#(lp,nPy)
rem calculate remainding distance for ball to travel in this frame
ry# = ball_yv#/(oEy#-collision_y#)
rx# = ball_xv#/(oEx#-collision_x#)
rem compute ball velocities
ball_xv#= 2*Nx#+ball_xv#
ball_yv#= 2*Ny#+ball_yv#
rem position ball in final position of frame
ball_start_x# = collision_x#+ball_xv#/rx#
ball_start_y# = collision_y#+ball_yv#/ry#
ink rgb(0,0,255),rgb(0,0,0)
circle ball_start_x#, ball_start_y#, 8
rem and show the new return vector
ball_end_x# = ball_start_x# + ball_xv#
ball_end_y# = ball_start_y# + ball_yv#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
return
Rem * Title : simple line collision
Rem * Author : trager
Rem * Date : 9-feb-2003
set text opaque
rem initialise the wall characteristics
dim wall#(2,12)
start_x = 0
start_y = 1
end_x = 2
end_y = 3
xv = 4
yv= 5
angle = 6
nPx = 7
nPy = 8
distance = 9
col_x = 10
col_y = 11
wall#(1,start_x) = 100
wall#(1,start_y) = 100
wall#(1,end_x) = 350
wall#(1,end_y) = 350
rem and wall 2
wall#(2,start_x) = 100
wall#(2,start_y) = 230
wall#(2,end_x) = 350
wall#(2,end_y) = 230
for lp = 1 to 2
rem get the x and y difference from start to end of wall
rem the x length and y length if you like
wall#(lp,xv) = wall#(lp,end_x) - wall#(lp,start_x)
wall#(lp,yv) = wall#(lp,end_y) - wall#(lp,start_y)
rem the angle of the wall
wall#(lp,angle) = atanfull(wall#(lp,xv),wall#(lp,yv))
wall#(lp,nPx) = 0-wall#(lp,yv)
wall#(lp,nPy) = wall#(lp,xv)
wall_length# = sqrt(wall#(lp,nPx)*wall#(lp,nPx) + wall#(lp,nPy)*wall#(lp,nPy))
rem normalise Perpendicular
wall#(lp,nPx) = wall#(lp,nPx)/wall_length#
wall#(lp,nPy) = wall#(lp,nPy)/wall_length#
rem draw a wall to test collision against
line wall#(lp,start_x), wall#(lp,start_y), wall#(lp,end_x), wall#(lp,end_y)
next lp
rem stage 0 asks for start position
rem stage 1 ask for end position
rem stage 2 calculates the point of collision
text 0,0,"Click the start position of the balls path"
stage = 0
ink rgb(255,0,0), rgb(0,0,0)
do
for lp = 1 to 2
wall#(lp,distance) =1000000
next lp
collision_count = 0
rem the user defines the start and end postion of balls path using_
rem mouse clicks in the desired location
if stage = 0 and mouseclick() =1
rem get the ball start position when user clicks the mouse for the first time
ball_start_x# = mousex()
ball_start_y# = mousey()
dot ball_start_x#, ball_start_y#
stage = 1
text 0,0," "
text 0,0,"Click the end position of the balls path"
wait 500
else
if stage = 1 and mouseclick() = 1
rem get the ball end position when the user clicks the mouse for the secound time
ball_end_x# = mousex()
ball_end_y# = mousey()
dot ball_end_x#, ball_end_y#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
circle ball_start_x#, ball_start_y#, 8
circle ball_end_x#, ball_end_y#, 8
rem get the speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
if ball_xv# = 0 then ball_xv# = 0.01
if ball_yv# = 0 then ball_yv# = 0.01
remstart
this part of the code increase the length of the line by adding 8 to the end of each line
this ensures that the collision is tested to the edge of the ball
rather than just to the centre of the balls resting position
remend
if ball_xv# <> 0 and ball_yv# <>0
rem we can predict the values of yR# and xR# acurately if the ball fails to
rem move along one of the axis.
R# = sqrt(ball_xv#*ball_xv# + ball_yv#*ball_yv#)
yR# = ball_yv#/R#
xR# = ball_xv#/R#
else
if ball_xv# = 0 and ball_yv# <> 0
rem if the ball has vertically but not horizontally
if ball_start_y# <= ball_end_y#
yR# = 1
xR# = 0
else
yR# = -1
xR# = 0
endif
else
if ball_start_x# <= ball_end_x#
yR# = 0
xR# = 1
else
yR#= 0
xR#=-1
endif
endif
endif
rem once we calculated how much to add on to each end of the line we do so
oEx# = ball_end_x#
oEy# = ball_end_y#
ball_end_y# = ball_end_y# + yR# * 8.0
ball_end_x# = ball_end_x# + xR# * 8.0
ball_start_y# = ball_start_y# - yR# * 8.0
ball_start_x# = ball_start_x# - xR# * 8.0
rem and then add a nice green line to show the line we will be testing
rem notice the green line goes from the back of the start ball to
rem the front of the finish ball
ink rgb(0,255,0),rgb(0,0,0)
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
rem get the new speed of the ball along the x and y axis
ball_xv# = ball_end_x# - ball_start_x#
ball_yv# = ball_end_y# - ball_start_y#
stage = 2
text 0,0," "
text 0,0,"Click left mouse button to get location of collision"
wait 500
else
if stage = 2 and mouseclick() = 1
rem on the third mouse click the program calculates the position of a collision
collision = 0
min_distance# = 1000000
for lp = 1 to 2
gosub show_collision
next lp
rem if there has been at least 1 collision then calculate the return values
rem this ensures that the ball bounces of the first wall it hits
if collision =1
lp = subscript
gosub calc_return
endif
wait 500
end
endif
endif
endif
sync
loop
show_collision:
remstart
this part of the code finds the collision point between the wall
and the balls path and then draws a circle around it
remend
rem now understanding how this next part works is not important
rem just know that this is the collision test basically it calcs s and t
rem if s and t are between 0 and 1 then there has been a collision
s# = ((0-ball_yv#) * (ball_start_x#-wall#(lp,start_x)) + ball_xv#*(ball_start_y#-wall#(lp,start_y))) / ((0-wall#(lp,xv))*ball_yv# + ball_xv#*wall#(lp,yv))
t# = (wall#(lp,xv) * (ball_start_y#-wall#(lp,start_y)) - wall#(lp,yv)* (ball_start_x#-wall#(lp,start_x))) / ((0-wall#(lp,xv))*ball_yv# + ball_xv#*wall#(lp,yv))
if (s# >=0 and s# <= 1) and (t# >= 0 and t# <=1)
rem only runs this part if a collision occured
gosub calc_ball_pos
collision = 1
endif
return
calc_ball_pos:
rem now we have established that there has been a collision we must calculate
rem where it is, again its not important that you understand this
rem just as long as you know what it does
rem once the collision point is calculated we draw a circle around it
rem to show where it is
rem this places the ball in the exact position of collision
rem so that the edge of the ball is touching the wall and not the ball centre
ra# =(atanfull(ball_xv#,ball_yv#) - wall#(lp,angle))
ras# = sqrt((1-cos(2*ra#))/2)
rem use a ball radius of 10 to allow for any discrepancies
cb# = 10 *(1-ras#) / ras#
ab# = sqrt(100 + cb#*cb#)
wall#(lp,col_y) = (ball_start_y# + (t# * ball_yv#)) - yR# * ab#
wall#(lp,col_x) = (ball_start_x# + (t# * ball_xv#)) - xR# * ab#
coll_x# =(ball_start_x#-wall#(lp,col_x))*(ball_start_x#-wall#(lp,col_x))
coll_y# =(ball_start_y#-wall#(lp,col_y))*(ball_start_y#-wall#(lp,col_y))
rem need this value to find the closest collision point to the start of the balls path
wall#(lp,distance) = sqrt(coll_x#+coll_y#)
rem check to see if this is the smallest distance so far
rem and store the distance and subscript if it is
if wall#(lp,distance) < min_distance#
min_distance# = wall#(lp,distance)
subscript = lp
endif
return
calc_return:
remstart
right then this little mess calculates the return velocities
of the ball after it has hit the wall, pretty aint it
again you dont have to understand how it works only recognise the wall and ball
variables
the blue circle now shows the final resting position of the ball after a colision
this means that the ball travels the exact distance dictate by its speed
so the calculation performs a rebound befor the next frame
the blue line is velocity vector of the next frame.
oEx# and oEy# are to new variables that store the old_end coordinates of the ball
ie the acutall point you click with the second mouse click before adding the green
line
remend
rem get N of ball
mulit# = 0-ball_xv#*wall#(lp,nPx)+ ball_yv#*wall#(lp,nPy)
Nx# = mulit#*wall#(lp,nPx)
Ny# = mulit#*wall#(lp,nPy)
rem calculate remainding distance for ball to travel in this frame
ry# = ball_yv#/(oEy#-wall#(lp,col_y))
rx# = ball_xv#/(oEx#-wall#(lp,col_x))
rem compute ball velocities
ball_xv#= 2*Nx#+ball_xv#
ball_yv#= 2*Ny#+ball_yv#
rem position ball in final position of frame
ball_start_x# = wall#(lp,col_x)+ball_xv#/rx#
ball_start_y# = wall#(lp,col_y)+ball_yv#/ry#
ink rgb(0,0,255),rgb(0,0,0)
circle ball_start_x#, ball_start_y#, 8
rem and show the new return vector
ball_end_x# = ball_start_x# + ball_xv#
ball_end_y# = ball_start_y# + ball_yv#
line ball_start_x#, ball_start_y#, ball_end_x#, ball_end_y#
return