Circles question

I am trying to write a piece of code which will place a number of circles that do not overlap, just touch at the edges on the screen. However i don’t think my code is doing what I think it is doing. If someone could help that would be great, thanks for any replies.


--# Main

function setup()
    num=100
    circs={}
    for i=1,num do
        local x,y=math.random(0,WIDTH),math.random(0,HEIGHT)
        local r=math.random(50,100)
        for n,c in ipairs(circs) do
            local dist=c.pos:dist(vec2(x,y))
            dist=dist-c.rad
            while dist<=0 do
                x,y=math.random(0,WIDTH),math.random(0,HEIGHT)
                dist=c.pos:dist(vec2(x,y))
                dist=dist-c.rad
                
            end
            r=math.min(dist,r)
        end
        table.insert(circs,Circ(x,y,r))
    end
end

function draw()
    background(0)
    for i=1,#circs do
        circs[i]:draw()
    end
end







--# Circ
Circ = class()

function Circ:init(x,y,r)
    self.pos=vec2(x,y)
    self.rad=r
end

function Circ:draw()
    pushStyle()
    ellipseMode(RADIUS)
    fill(255,50)
    ellipse(self.pos.x,self.pos.y,self.rad)
    popStyle()
end

@Coder You need to create a table that has the x,y,radius values. Then each time you want to create another circle, you need to check each circle in the table to make sure you’re not creating a new circle inside an existing one.

@Coder, the most obvious thing I see is your line while dist <= 0 this would be ignored unless the circles are exactly on top of each other, or the first one is on the left (i believe). try changing it to while math.abs(dist) < c.rad + r this will be true only if the distance between the center of the two circles is less than their radii added together - i.e. they are overlapping

@Coder Here’s an easy way.


displayMode(FULLSCREEN)

function setup()
    physics.continuous=true
    circ={}
    count=0
    e1=physics.body(EDGE,vec2(0,0),vec2(0,HEIGHT))
    e2=physics.body(EDGE,vec2(0,0),vec2(WIDTH,0))
    e3=physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT))
end

function draw()
    background(40,40,50)
    noFill()
    stroke(255)
    strokeWidth(2)
    if count<300 then
        count=count+1
        c=physics.body(CIRCLE,math.random(5,50))
        c.x=math.random(WIDTH)
        c.y=1.5*HEIGHT
        table.insert(circ,c)
    end
    for a,b in pairs(circ) do
        ellipse(b.x,b.y,b.radius*2+2)
    end  
end

@Coder Here’s another version.


displayMode(FULLSCREEN)

function setup()
    circ={}
    loop=0
    min=20
    max=80
    circles=800
    while loop<circles do
        x=math.random(WIDTH)
        y=math.random(HEIGHT)
        d=max
        ok=true
        for a,b in pairs(circ) do
            v1=vec2(x,y)
            dis=v1:dist(vec2(b.x,b.y))
            if dis<b.z/2 then
                ok=false   
                loop=loop+1   
            elseif dis-b.z/2<d then
                d=dis-b.z/2
            end
        end
        if ok then
            if d<max then
                d=d*2
            end
            if d>min then
                table.insert(circ,vec3(x,y,d))
            end
        end
    end
end

function draw()
    background(40, 40, 50)
    noFill()
    stroke(255)
    strokeWidth(2)
    for a,b in pairs(circ) do
        ellipse(b.x,b.y,b.z+2)
    end
end

Here’s another version of non overlapping circles.


displayMode(FULLSCREEN)

function setup()
    circ={}
    col={}
    min=5
    max=50
end

function draw()
    background(0)
    for a,b in pairs(circ) do
        fill(col[a])
        ellipse(b.x,b.y,b.z+2)
    end
    x=math.random(WIDTH)
    y=math.random(HEIGHT)
    d=max
    ok=true
    for a,b in pairs(circ) do
        v1=vec2(x,y)
        dis=v1:dist(vec2(b.x,b.y))
        if dis<b.z/2 then
            ok=false   
        elseif dis-b.z/2<d then
            d=dis-b.z/2
        end
    end
    if ok then
        if d<max then
            d=d*2
        end
        if d>min then
            table.insert(circ,vec3(x,y,d))  
            table.insert(col,color(math.random(255),
                math.random(255),math.random(255)))
        end
    end
end

Thanks for the replies everyone, I will have to disect you code to see how it works