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)


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


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

@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)

function draw()
    background(40, 40, 50)
    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)

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

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

Have a look at this:

@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.