Beautiful, isn't it? It might look complex but it's mathematically quite impressive. Making this pattern wasn't hard but it definitely took a lot of trial and error to get it right and honestly, I don't really know if it's this is the most efficient way to generate this pattern.

This article isn't a tutorial but rather, I'll be talking about the algorithm itself. However, you can check out the source code in my GitHub repository.

## How it works?

In order to achieve that "stacked" effect, there are two things to keep in mind:

- Generate circles with a random radius
- Look for collisions with other circles

The logic is quite similar to the Overlapping Rectangles problem except this is done with circles.

## Generate circles with dynamic radius

This method will help generate valid circles with a random radius. Circles that don't overlap or collide with other circles are considered to be valid.

```
// Generate a valid circle
const generateCircle = () => {
let newCircle;
let isValidCircle = false;
for(let i=0; i<attempts; i++) {
newCircle = {
x: Math.floor(Math.random() * width),
y: Math.floor(Math.random() * width),
radius: minRadius
};
if(checkForCollision(newCircle)) {
continue;
}
else {
isValidCircle = true;
break;
}
}
if(!isValidCircle) { return; }
for(let i=minRadius; i<=maxRadius; i++) {
newCircle.radius = i;
if(checkForCollision(newCircle)) {
newCircle.radius--;
break;
}
}
circles.push(newCircle);
drawCircleOnCanvas(context, newCircle, colors[Math.floor(Math.random() * colors.length)]);
}
```

## Look for collision with other circles

Thanks to some online research, I was able implement the Euclidean Distance equation that helped with calculating the distances between each circle and detect for collisions. Along with that, I also found another article on Touching Circles that was quite useful.

These are the formulas used to detect the collision:

Find the distance between two centres \[ AB = \sqrt{ (x2 - x1)^2 - (y2 - y1)^2} \]

Calculate the radii of both circles. \[R = r1 + r2\]

If the radii is greater than or equal to the euclidean distance of both circles, then it's a valid circle with no collisions.

```
// Check for collision in a canvas
const checkForCollision = (newCircle) => {
let x2 = newCircle.x;
let y2 = newCircle.y;
let r2 = newCircle.radius;
// Determine the euclidean distance between two circle
// using Pythagorean Theorem.
// Refer to:
// https://en.wikipedia.org/wiki/Euclidean_distance
for(let i=0; i<circles.length; i++) {
let otherCircle = circles[i];
let r1 = otherCircle.radius;
let x1 = otherCircle.x;
let y1 = otherCircle.y;
let xx = ((x2 - x1) * (x2 - x1));
let yy = ((y2 - y1) * (y2 - y1));
let radii = r2 + r1;
let euclidDistance = Math.sqrt(xx + yy);
if(radii >= euclidDistance) {
return true;
}
}
// Check collision on top
if(x2 + r2 >= width ||
x2 - r2 <= 0) {
return true;
}
// Check collision on bottom
if(y2 + r2 >= width ||
y2 - r2 <= 0) {
return true;
}
//else return false
return false;
}
```

## Conclusion

I'm thinking of implementing more generative patterns like Triangular Mesh and Piet Mondrian's Red, Blue and Yellow composition.

Hope you liked reading this article.

Stay tuned for more!