I already considered a recursive method to handle that issue, I just haven't bother with an implementation yet until I get the initial collision perfectly.
Here's my example for trial 2. If you play around with it a little bit you can see it doesn't always work.
set display mode 1280, 768, 32
Type Vector2D
x as float
y as float
EndType
A as Vector2D
B as Vector2D
C as Vector2D
D as Vector2D
rem starting position for sphere
A.x = 300
A.y = 620
rem collision line
C.x = 200
C.y = 375
D.x = 200
D.y = 175
rem sphere radius
radius = 40
dim map(19, 24) as dword
map(9,10) = rgb(0,128,255)
map(10,10) = rgb(0,128,255)
map(9,11) = rgb(0,128,255)
map(10,11) = rgb(0,128,255)
sync on
do
cls
for x = 0 to 19
for y = 0 to 24
if map(x, y) > 0
ink map(x,y),0
box x*64, y*32, x*64+64, y*32+32
endif
next y
next x
ink rgb(48,48,48),0
for x = 1 to 19
line x*64, 0, x*64, 768
next x
for y = 1 to 24
line 0, y*32, 1280, y*32
next y
rem ending position for sphere
B.x = mousex()
B.y = mousey()
rem unit normal of line
nx# = -(D.y-C.y)
ny# = (D.x-C.x)
d# = sqrt(nx#*nx# + ny#*ny#)
nx# = nx# / d#
ny# = ny# / d#
rem set normal for vertical lines
nx# = 1
ny# = 0
if B.x - A.x > 0
nx# = -1
endif
rem check all vertical lines
u0# = 100
for x = 0 to 19
C.x = x*64
C.y = 0
D.x = x*64
D.y = 768
rem calculate dot products
d0# = (A.x-C.x)*nx# + (A.y-C.y)*ny#
d1# = (B.x-C.x)*nx# + (B.y-C.y)*ny#
rem calculate time at which sphere collides with line
u# = (d0# - radius) / (d0#-d1#)
rem Same result as the commented equation above,
rem only in a simpler form of linear interpolation.
ix# = A.x + (B.x-A.x)*u#
iy# = A.y + (B.y-A.y)*u#
rem Point of contact
wx# = ix# - nx#*radius
wy# = iy# - ny#*radius
row = wy# / 32
col = wx# / 64
if nx# > 0 then dec col
remstart
rx# = D.x - C.x
ry# = D.y - C.y
n# = ((ix# - C.x)*rx#) + ((iy# - C.y)*ry#)
d# = rx#^2 + ry#^2
ru# = n# / d#
remend
if u# >= 0 and u# <= 1
if map(col, row) > 0
if u# < u0#
u0# = u#
tix# = ix#
tiy# = iy#
wix# = wx#
wiy# = wy#
endif
endif
endif
next x
rem set normal for horizontal lines
nx# = 0
ny# = 1
if B.y - A.y > 0
ny# = -1
endif
rem check all horizontal lines
for y = 0 to 24
C.x = 0
C.y = y*32
D.x = 1280
D.y = y*32
rem calculate dot products
d0# = (A.x-C.x)*nx# + (A.y-C.y)*ny#
d1# = (B.x-C.x)*nx# + (B.y-C.y)*ny#
rem calculate time at which sphere collides with line
u# = (d0# - radius) / (d0#-d1#)
rem Same result as the commented equation above,
rem only in a simpler form of linear interpolation.
ix# = A.x + (B.x-A.x)*u#
iy# = A.y + (B.y-A.y)*u#
rem Point of contact
wx# = ix# - nx#*radius
wy# = iy# - ny#*radius
row = wy# / 32
col = wx# / 64
if ny# > 0 then dec row
if u# >= 0 and u# <= 1
if map(col, row) > 0
if u# < u0#
u0# = u#
tix# = ix#
tiy# = iy#
wix# = wx#
wiy# = wy#
endif
endif
endif
next y
rem new position of circle after collision intersection
ink rgb(255,255,0),0
circle tix#, tiy#, radius
rem Point of contact along the line where the circle hits
ink 0xff00ff00
circle wix#, wiy#, 3
`text wix#, wiy#, str$(col)+":"+str$(row)
`text wx#, wy#+16, str$(ru#)
ink rgb(255,0,0),0
rem show trail
for i = 1 to 10
t# = i / 10.0
if t# < u0#
x = A.x + (B.x-A.x)*t#
y = A.y + (B.y-A.y)*t#
circle x, y, radius
endif
next i
if mouseclick()
A.x = mousex()
A.y = mousey()
endif
rem get intersection point
rem Find center of sphere at point of intersection by
rem interpolating by the affine combination of A and B.
`ix# = (1-u#)*A.x + u#*B.x
`iy# = (1-u#)*A.y + u#*B.y
rem starting circle
ink -1, 0
circle A.x, A.y, radius
rem line showing current circle position to destination
line A.x, A.y, B.x, B.y
set cursor 0,0
print "u: ",u#
sync
loop
rem verifies a number is within the specified range
function inRange(n as float, low as float, high as float)
if n >= low and n <= high then exitfunction 1
endfunction 0
rem Returns time value along line AB for intersection with line CD
function timeIntersection(A as vector2D, B as vector2D, C as vector2D, D as vector2D)
n# = ((D.x-C.x) * (A.y-C.y)) - ((D.y-C.y) * (A.x-C.x))
d# = ((D.y-C.y) * (B.x-A.x)) - ((D.x-C.x) * (B.y-A.y))
t# = n# / d#
endfunction t#
"You're all wrong. You're all idiots." ~Fluffy Rabbit