# Coldet - Functions for collision detection

#### TheMrCerebro

##### New Member
Hello everyone!!!

These are some very useful functions to detect collisions in different ways, each one will use the one that best suits your game or application. I do not think they need examples, they are very intuitive to use.

Note: Many of the functions I have not tried, but I hope they work.

Code:
``````#rem
Created by http://benmoren.com
Some functions and code modified version from http://www.jeffreythompson.org/collision-detection
Version 0.1 | January 10th, 2016
#end

'Version for Cerberus-X by TheMrCerebro

'[~++~+~+~++~+~++~++~+~+~ 2D ~+~+~++~+~++~+~+~+~+~+~+~+~+~+~+]

Function colRectRect(x#, y#, w#, h#, x2#, y2#, w2#, h2#)

'add in a thing to detect rectMode CENTER
If (x + w >= x2 And x <= x2 + w2 And y + h >= y2 And  y <= y2 + h2) Return True
Return False

End

Function colRectCircle(rx#, ry#, rw#, rh#, cx#, cy#, diameter#)

'temporary variables to set edges for testing
Local testX# = cx
Local testY# = cy

'which edge is closest?
If (cx < rx)
testX = rx 'left edge
Else If (cx > rx+rw)
testX = rx+rw 'right edge
endif

If (cy < ry)
testY = ry 'top edge
Else If (cy > ry+rh)
testY = ry+rh 'bottom edge
endif

'get distance from closest edges
Local distance# = Sqrt( Pow(cx-testX,2)+Pow(cy-testY,2) )

'if the distance is less than the radius, collision!
if (distance <= diameter/2) return true

Return False

End

Function colCircleCircle(x#, y#, d#, x2#, y2#, d2#)

If Sqrt( Pow(x-x2,2)+Pow(y-y2,2) ) <= (d/2)+(d2/2) Then Return True
Return False

End

Function colPointCircle(x#, y#, cx#, cy#, d#)

If Sqrt( Pow(x-cx,2)+Pow(y-cy,2) ) <= d/2 Then Return True
Return False

End

Function colPointPoint(x1#, y1#, x2#, y2#)

'are the two points in the same location?
if (x1 = x2 and y1 = y2) then return true
Return False

End

Function colPointRect(pointX#, pointY#, x#, y#, xW#, yW#)

If (pointX >= x And pointX <= x + xW And pointY >= y And pointY <= y + yW) Then Return True
Return False

End

function colLineRect(x1#, y1#, x2#, y2#, rx#, ry#, rw#, rh#)

'check if the line has hit any of the rectangle's sides
'uses the Line/Line function below
Local left?   = colLineLine(x1,y1,x2,y2, rx,ry,rx, ry+rh)
Local right?  = colLineLine(x1,y1,x2,y2, rx+rw,ry, rx+rw,ry+rh)
Local top?    = colLineLine(x1,y1,x2,y2, rx,ry, rx+rw,ry)
Local bottom? = colLineLine(x1,y1,x2,y2, rx,ry+rh, rx+rw,ry+rh)

'if ANY of the above are true, the line has hit the rectangle
If (left or right or top or bottom) Then Return True

Return False

end

Function colLineLine(x1#, y1#, x2#, y2#, x3#, y3#, x4#, y4#)

'calculate the direction of the lines
Local uA# = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1))
Local uB# = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1))

'if uA and uB are between 0-1, lines are colliding
if (uA >= 0 and uA <= 1 and uB >= 0 and uB <= 1) then Return True

Return False

end

Function colLineCircle(x1#, y1#, x2#, y2#, cx#, cy#, r#)

'is either end INSIDE the circle?
'if so, return true immediately
Local inside1? = colPointCircle(x1,y1, cx,cy,r)
local inside2? = colPointCircle(x2,y2, cx,cy,r)
if (inside1 or inside2) return true

'get length of the line
Local distX# = x1 - x2
Local distY# = y1 - y2
Local len# = Sqrt( (distX*distX) + (distY*distY) )

'get dot product of the line and circle
Local dot# = ( ((cx-x1)*(x2-x1)) + ((cy-y1)*(y2-y1)) ) / Pow(len,2)

'find the closest point on the line
Local closestX# = x1 + (dot * (x2-x1))
Local closestY# = y1 + (dot * (y2-y1))

'is this point actually on the line segment?
'if so keep going, but if not, return false
Local onSegment? = colLinePoint(x1,y1,x2,y2, closestX,closestY)
If Not onSegment Then Return False

'get distance to closest point
distX = closestX - cx
distY = closestY - cy
Local distance# = Sqrt( (distX*distX) + (distY*distY) )

If (distance <= r) Then Return True

return false

end

Function colLinePoint(x1#, y1#, x2#, y2#, px#, py#)

'get distance from the point to the two ends of the line
Local d1# = dist(px,py, x1,y1)
local d2# = dist(px,py, x2,y2)

'get the length of the line
Local lineLen# = dist(x1,y1, x2,y2)

'since floats are so minutely accurate, add
'a little buffer zone that will give collision
Local buffer# = 0.1 'higher # = less accurate

'if the two distances are equal to the line's length, the
'point is on the line!
'note we use the buffer here to give a range, rather than one #
If (d1+d2 >= lineLen-buffer and d1+d2 <= lineLen+buffer) Then Return True

Return False

End``````

#### Attachments

• 4.2 KB Views: 95
• 3.2 KB Views: 72

#### Holzchopf

##### Moderator
Staff member
Thanks, very handy!

But I think the colLineRect function is missing the 'is either end INSIDE the circle?-part (like the colLineCircle has) and therefore won't trigger when a line is completely inside the rect.

Also I'd prefer having full Pascal case function names. E.g. CollideRectRect, CollideRectCircle and so on.