# Circle edge overlap

I have two circles and know the positions of their centre’s and their radii. I know that these circles overlap but how can I find the two points at which their circumferences cross

@Kjell thanks that was exactly what I needed.

Oh yeah, it was actually a random number affecting the sizes on the circles.(silly me)

Thanks

@Kjell Looks good to me, but you could make it slightly more efficient.

(untested)

``````function circlesIntersect(pos1, r1, pos2, r2)
local d = pos1:dist(pos2)
local v = pos2 - pos1
-- scale so that the distance between the circles is 1
r1 = r1/d
r2 = r2/d

if r1+r2 > 1 and math.abs(r1 - r2) < 1 then
local x = (r1^2 -r2^2 + 1)/2
local mid = x*v + pos1
local y = math.sqrt(r1^2 - x^2)*v:rotate90()
return mid + y, mid - y, mid
end
end
``````

@Kjell I’ve never seen this syntax before: `noStroke(); fill(255)` but it seems that if I change the space between the semi colon and the fill() it changes the size if the circles. So what is the purpose of the semi colon- I’ve never seen one before in lua

According to this stackexchange question, semi-colons are just used to separate statements on the same line so changing the spacing shouldn’t affect what’s happening.

I came up with this. The function at the bottom is the one that finds the intersections, called circlesIntersect. If you want, I can post the underlying geometry that I used to make this tomorrow (it’s not so hard!).

``````--# Main
-- Circles

function setup()
r1 = 50 + math.random()*100
r2 = 50 + math.random()*100

pos1 = vec2(0, 0)
pos2 = vec2(WIDTH/2, HEIGHT/2)
end

function draw()
background(40, 40, 50)

ellipseMode(CENTER)
strokeWidth(2); stroke(255)
fill(255, 0, 0, 127)
ellipse(pos2.x, pos2.y, 2*r2)

fill(0, 0, 255, 127)
ellipse(pos1.x, pos1.y, 2*r1)

noStroke(); fill(255)
ellipse(pos1.x, pos1.y, 10)
ellipse(pos2.x, pos2.y, 10)

s1, s2, mid = circlesIntersect(pos1, r1, pos2, r2)
if s1 then  -- Only draw if intersections are returned
fill(255, 0, 0, 255)
ellipse(s1.x, s1.y, 10)
ellipse(s2.x, s2.y, 10)
ellipse(mid.x, mid.y, 10)
end
end

function touched(touch)
pos1 = vec2(touch.x, touch.y+100)
end

function circlesIntersect(pos1, r1, pos2, r2)
local d = pos1:dist(pos2)
local angle = vec2(1,0):angleBetween(pos2-pos1)

if d < r1+r2 and d > math.abs(r1 - r2) then
local x = (r1^2 -r2^2 + d^2)/(2*d)
local mid = pos1 + vec2(x, 0):rotate(angle)

local y = math.sqrt(r1^2 - x^2)
local s1 = mid + vec2(y, 0):rotate(angle + math.pi/2)
local s2 = mid + vec2(y, 0):rotate(angle - math.pi/2)

return s1, s2, mid
end
end
``````

Have a look at this:

http://www.analyzemath.com/CircleEq/circle_intersection.html

@Coder The semi colon isn’t even necessary, since Lua ignores all spaces and returns. But I use it anyway, for better readability.

@LoopSpace That does indeed look better. You’re making better use of vector calculations than I was. Looks cleaner.

EDIT: Whoopsie, double post.