DistanceBasedCollision

Collision between two circles

Another way of detecting collisions. This type works perfectly with circles. It checks if the distance of one object to the other is less than the sum of their radii (plural of radius.)

Variable Definitions : x1, y1, r1 = first circle's center coordinates and radius; x2, y2, r2 = second circle's center coordinates and radius.

function checkCircularCollision(x1, y1, r1, x2, y2, r2)
	local dx = x2 - x1
	local dy = y2 - y1
	local dist = math.sqrt(dx * dx + dy * dy)
	return dist < r1 + r2
end

Don't want an extra square root function? Try this other function

function checkCircularCollision(x1, y1, r1, x2, y2, r2)
	local dx, dy, sr = x2 - x1, y2 - y1, r1 + r2
	return dx*dx + dy*dy < sr*sr
end

Although I do keep the sqrt function to know that I am dealing with distances.

Do note that while the second may seem faster since it avoids a costly square root, that's still one function, instead of the second version's three squarings. That said, Löve uses LuaJIT, so if one really needs to optimize, check which is faster.

Collision between circle and rectangle

function checkCircleToRectangleCollision(cx, cy, cr, rectX, rectY, rectW, rectH)
	local nearestX = math.max(rectX, math.min(cx, rectX + rectW))
	local nearestY = math.max(rectY, math.min(cy, rectY + rectH))
	local dx, dy = math.abs(cx - nearestX), math.abs(cy - nearestY)
	if dx > cr or dy > cr then return false end
	return dx*dx + dy*dy < cr*cr
end


Collision between circle and polygon

function checkCircleToRectangleCollision(cx, cy, cr, poly)
	local function nearestPolygonPoint(cx, cy, x1, y1, dx, dy)
		local d = dx * dx + dy * dy
		if d == 0 then return x1, y1 end -- length was 0
		local t = ((cx - x1) * dx + (cy - y1) * dy) / d
		t = math.max(0, math.min(1, t))
		return x1 + t * dx, y1 + t * dy
	end

	local x1, y1 = poly[#poly - 1], poly[#poly]
	local x2, y2 = poly[1], poly[2]
	for i = 1, #poly-1, 2 do
		local nearestX, nearestY = nearestPolygonPoint(cx, cy, x1, y1, x2-x1, y2-y1)
		local dx, dy = cx - nearestX, cy - nearestY
		if dx*dx + dy*dy < cr*cr then
			return true  -- Collision detected
		end
		x1, y1, x2, y2 = x2, y2, poly[i+2], poly[i+3]
	end
	return false
end



Other Languages