We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi! So here's the code to Daniel Shiffman's circle packing problem. I want to make some modifications.
Also, I want the r1 circles to be of specific distance from each other. Like all r1 sized circles should be 120 pixels apart from each other.
var circles = [];
function setup() {
createCanvas(600, 600);
var protection = 0;
while(circles.length<300) {
var circle = {
x:random(width),
y:random(height),
r:random(10, 30)
}
var overlapping = false;
for(var j = 0; j<circles.length; j++){
var other = circles[j];
var d = dist(circle.x, circle.y, other.x, other.y);
if(d<circle.r + other.r){
overlapping = true;
}
}
if (!overlapping) {
circles.push(circle);
}
protection++;
if (protection > 10000) {
break;
}
}
for (var i = 0; i < circles.length; i++) {
fill(255, 0, 175, 100);
noStroke();
ellipse(circles[i].x, circles[i].y, circles[i].r * 2, circles[i].r * 2);
}
}
Answers
Do you mean right beside each other or to be placed on the surface while none of them overlap with each other?
Kf
For them to be right beside each other, @kfrajer
https://forum.processing.org/two/discussion/15473/readme-how-to-format-code-and-text#latest
Get this right. It's basically a prereq for people here to help you.
@TfGuy44 There it is. I'm sorry and thank you!
When you know the left edge of the box you can calculate the position of first circle by saying boxX + radius1
The second circle is this value plus radius2
You can use dist() to find out the distance
Maybe you read about (recursive) backtracking algorithm which would be one way of attacking this
Or you think like you have an imaginary list of 300 circles (different sizes) then you do all permutations and check each of them how many fit in the box (all circles would never fit but the order would be different every time.). An additional Variation is the placement when you're planning to place the boxes on x and y coordinates (when the box is higher than your circles diameter)
Chrisir
Okay. Now that I can actually read the code you have posted without my eyes bleeding, I can see that it is generating a random candidate circle, checking it against all already placed circles, and then only placing the candidate circle if it doesn't create any overlaps.
Since it's the easiest thing to change, we might as well do it first: You only want three sizes of circles. So let's see what happens to this sketch if we only have three sizes of circles:
Notice the changes here. The r property of a circle now ranges from 0 to 2. 0 means a small circle. 1 is a medium circle. 2 is a large circle. the valid_sizes[] array stores the sizes, and the circle's r property is used as an index into that array in all places where a radius was expected before (including in the code that checks for overlaps and drawing the circle!). A valid_colors[] array has also been added to draw each size in a different color. As before, r is the index into that array.
@Tfguy44 , this is amazing! Thank you! Is it also possible to put the circles right beside each other such that no space is wasted? My research is about space optimization.
Show your attempt please - did you read my post and the Wikipedia article? Tfguy can't do your work for you, that would be cheating, right?
Here it is, @Chrisir . I just think my codes aren't any good.
In which way aren't they good? What do you dislike? What needs change, what did you try?
@Chrisir
Hmm. Well, I couldn't get to combine two algorithms. I can make it that the circles are right beside each other BUT only with 1 size of circle, I need 3 sizes. I can make it generate 3 sizes of circles BUT the circles won't be beside each other. I can't seem to figure out a way to combine those two. And my code is structured as that it will not stop until the loop is finished instead of stopping when there's no space to put another circle in. Well, to summarize it all, what I need is for it to generate 3 sizes of circles (c1, c2 and c3) such that c1 types of circles are a certain distance apart from each other but all circles are right beside each other without overlap. From my attempts, they can be done separately, but I just can't put them all together.
Well you need a counter how much space you used already with the circles up to now.
For a new circle, add its diameter to the counter.
How would you do this?
@Chrisir , that is for the part where my c1 circles are a certain distance from each other, right? I think I already got that part in my code there with the variable newr3 distance . The part I cannot get here is how to put them right beside each other.
You mean how to put them graphically?
Just reduce x-value until
dist
(.....)<=
sum of radius of both circles (or see my post above)Here's the latest update. Got it to count the circles and actually put a certain distance to the one of the 3 types of circles which I thought I already did earlier, my bad. Thank you @Chrisir and @TfGuy44 for guiding me here! Just one more modification is missing, the part where dist = 0 among all the circles. I am still trying to understand what Chrisir is saying.
You really have to dig into it to solve this. Read it carefully tell yourself what's happening in every line and understand the code
Then you'll be able to solve it.
It's an art.
Right now you are placing your largest circles in a grid, and then trying to place smaller circles at random (by making sure there are no overlaps).
If you want there to no space between randomly placed circles - that is, the candidate circle is touching an existing circle, you'll need to do some stricter checking. Not only will it have to be placed in a spot that it doesn't overlap any other circle, but it will also have to be placed in a spot so that the distance between it and some other circle is just enough for them to look like they are touching.
You can add this check, but then you have a different problem: How likely is it that your candidate circle is randomly put in such a "good" position? Not very!
@TfGuy44 oh, yeah. Wow. :/ So the only solution here might be to make the code check every point in the canvass, right? Or is it not even possible that way?
It's possible, but it is a lot of wasted effort. As has been said many times already, circle packing is not an easy problem!
If you really want my advice, here it is: Forget this approach. Instead, get a physics engine. Heck, Box2D's CollisionListening example has everything you'd need.
@TfGuy44 just when i'm really getting into it. Well, guess I don't have a choice. I'm no expert in this. Haha. Thanks for the help and advice!
I guess it's a task from university / school.
It's an optimization problem.
A physics engine is probably not allowed then.
Read the articles on wikipedia for packing problems, backtracking, optimization etc.
My ideas with the permutation is also not too bad I guess
but there must be a formula you can find on google
Tinkering with it and I got this:
Do with this as you like - I'm unwilling to help beyond this point.
Will do, @Chrisir! Thanks! :)
And i'll try that out when I figure out how this box2d thing works, @TfGuy44 . Thanks! :)
Sketch > Import Library... > Add Library... > Add "Box2D for Processing"