It's working, but I have a minor issue. The direction of the normal determines which side of the line the intersection happens. In 3D this is probably ok because you often won't be colliding with the backface of a polygon. But in 2D, I could hit these lines from any direction.
Swapping the normal to point the other direction is simple:
nx# = -nx#
ny# = -ny#
In my other collision examples, I've always just focused on the collision point right on the line itself, no need for normals making for much faster calculations. However, I need to detect for collision between lines and a ball of a given radius, so this was a different approach for me.
I read an article on gamasutra a few times and after awhile I believe I understand where their math came from to get these results. However, I'm trying to find out a way to place the ball on the side of the line it came from so I don't have to worry about the direction of the normal.
I know it's easy enough to determine which direction the ball is traveling in regard to the lines, but I was hoping to find a way to skip that check.
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 = 420
rem collision line
C.x = 100
C.y = 375
D.x = 450
D.y = 175
rem sphere radius
radius = 40
sync on
do
cls
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 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 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 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
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
rem collision line
ink rgb(0,128,255),0
line C.x, C.y, D.x, D.y
rem new position of circle after collision intersection
ink rgb(255,255,0),0
circle ix#, iy#, radius
rem Point of contact along the line where the circle hits
ink 0xff0000
circle wx#, wy#, 3
sync
loop
"You're all wrong. You're all idiots." ~Fluffy Rabbit