# Populate area with circles based on image no overlap

I’m sure I saw someone with the same question on here not too long ago, but I can’t find it for the life of me.

I guess what Im trying to achieve is circle packing but with a more efficient way of filling the space rather than randomly waiting for a free space to be “picked” like in Daniel Shiffman’s coding challenge.

I’d also want to keep the circles all the same size.

thanks for any help

1 Like
1 Like

Hi @TimoL,

If I understand correctly, you would like to have:

• circles of same size
• packed (no overlapping)
• within a specific area
• almost instantly

One solution would be to display circles at each corner of a grid spreading all over the canvas. The unit size of that grid would be the desired diameter of your circles. You could then create/load a specific shape with the Geomerative library and only draw the circles whose location is in that shape.

Annotated example sketch (Python mode)

``````add_library('geomerative')

W, H = 1000, 600 #Dimensions of canvas
D = 8 #Desired diameter (circle)
w, h = W/D, H/D  #Scaled dimensions

def setup():
size(W, H, P2D)
background(255)
smooth(8)

RG.init(this) #Intitialize the library

rpoly = RPolygon() #Create an empty polygon

for i in xrange(360):
x = 16 * pow(sin(radians(i)), 3)
rpoly.addPoint(RPoint(width/2 + x*10, height/2 - y*10))

#Create a RShape object from polygon
heart = RShape(rpoly.toShape())

#Display circles all over the canvas
for i in xrange(w * h):
x = (i%w) * D
y = (i/w) * D

#Only draws those within the heart shape
if heart.contains(RPoint(x, y)):
ellipse(x, y, D, D)
``````

1 Like

Thanks @solub
Yea those are the requirements.
The grid idea will work I suppose but I’m not sure if that’s optional packing.
Also I think I’d prefer a more irregular arrangement.

I wonder if I add a bit of random to the grid arrangement perhaps?

According to Wikipedia:

the highest-density lattice arrangement of circles is the hexagonal packing arrangement,[2] in which the centres of the circles are arranged in a hexagonal lattice (staggered rows, like a honeycomb), and each circle is surrounded by 6 other circles.

So you could use the same sketch and just add an offset:

``````add_library('geomerative')

W, H = 1000, 600 #Dimensions of canvas
D = 8 #Desired diameter (circle)
w, h = W/D, H/D  #Scaled dimensions

def setup():
size(W, H, P2D)
background(255)
smooth(8)

RG.init(this) #Intitialize the library

rpoly = RPolygon() #Create an empty polygon

for i in xrange(360):
x = 16 * pow(sin(radians(i)), 3)
rpoly.addPoint(RPoint(width/2 + x*10, height/2 - y*10))

#Create a RShape object from polygon
heart = RShape(rpoly.toShape())

#Display circles all over the canvas
for i in xrange(w * h):
x = (i%w) * D
y = (i/w) * D

if (i/w)%2 == 0:
offset = D/2
else:
offset = 0

#Only draws those within the heart shape
if heart.contains(RPoint(x + offset, y)):
ellipse(x + offset, y, D, D)
``````

If you prefer an irregular look, Poisson-Disk Sampling could also be an option, but the packing won’t be optimal.

EDIT: Java version without dependencies

``````int W = 1000, H = 600; //Dimensions of canvas
int D = 8; //Desired diameter (circle)
int w = W/D, h = H/D;  //Scaled dimensions

PShape heart;
float offset;

void setup(){
size(1000, 600, P2D);
background(255);

//Create heart shape (heart formula)
heart = createShape();
heart.beginShape();
for (int i = 0; i < 360; i++){
float x = 16 * pow(sin(radians(i)), 3);
heart.vertex(width/2 + x*10, height/2 - y*10);
}
heart.endShape();

//Grid coordinates
for (int i = 0; i < w*h; i++){
float x = (i%w);
float y = (i/w);

//Offset
offset = (y%2 == 0) ? D/2 : 0;

//Only draw circles within the heart shape
if (contains(heart, x*D + offset, y*D)){
ellipse(x*D + offset, y*D, D, D);
}

}

noLoop();

}

//Function to determine whether a point is inside a shape/polygon or not
boolean contains(PShape shp, float x, float y){
int N = shp.getVertexCount();
boolean c = false;
for (int i = 0; i < N-1; i++){
PVector v1 = shp.getVertex(i+1);
PVector v2 = shp.getVertex(i);
if ((v2.y > y) != (v1.y > y)){
if (x < (v1.x - v2.x) * (y - v2.y) / (v1.y - v2.y) + v2.x){
c = !c;
}
}
}
return c;
}
``````
1 Like

This is exactly what I was looking for
Thanks so much!