- Home /
How to randomly generate non-intersecting cylinders within a circle?
I posted this question a while ago but unfortunately I've been unable to solve it with the answers provided. Also, I've had a look on Stack Overflow for similar questions but they're way over my head. So apologies for creating a new thread, but I'm hoping for some more suggestions.
Basically, I want to randomly generate a bunch of non-intersecting cylinders of varying size within a circle, much like an Ishihara colour test:
Colour is unimportant, I just need to be able to define the minimum distance between each circle. Any help is much appreciated.
Here's my code so far:
public Transform circle;
public int numberOfCircles;
public int circleSize;
void Start()
{
for (int i = 0; i < numberOfCircles; i++)
{
circleSize = Random.Range(1, 4);
circle.localScale = new Vector3(1 * circleSize, 1, 1 * circleSize);
Vector2 pos = Random.insideUnitCircle * 10;
Vector3 newPos = new Vector3(pos.x, 0, pos.y);
Instantiate(circle, newPos, Quaternion.identity);
}
}
And here's an example result, with 25 circles.:
As you can see, there's a lot of intersecting, and the circles don't really form the shape of a larger one.
I suppose I could just instantiate a hundred or so circles then destroy them until there is none intersecting, but I'm sure there is a more elegant solution.
Answer by Owen-Reynolds · Feb 01, 2014 at 06:27 PM
This a standard algorithm/math question. StackOverflow is probably the best place for it.
It's a difficult problem. In your image, note how the largest size is scattered evenly. Do you need that? And the next smaller size is 1/2 of the largest. Do you want that, or prefer random sizes? Do you need the tiny dots? What is the least amount of space where you need to add a tiny dot? In general, what ratio/distribution of large to small dots do you want?
I think the answers are confusing because the problem is hard and has lots of ways to do it.
Once you have a list of Vector3's and sizes, the Unity part to spawn them is easy.
For fun, a "Unity" way might be to make a half-circle collider (mesh, or build from many boxes.) Then spawn a pile of random cylinders and let them fall in Once they settle down, record positions.
Thanks Owen.
In your image, note how the largest size is scattered evenly. Do you need that?
No, I just need each circle to be at least a certain distance from one another.
And the next smaller size is 1/2 of the largest. Do you want that, or prefer random sizes?
At the moment, I'm Instantiating cylinders of three sizes.
In general, what ratio/distribution of large to small dots do you want?
Ideally, I would like for it to be a fairly even split.
$$anonymous$$y point is, you still have to refine the question before it can be answered (do you need three exact sizes, or would you be happy with shrinking/growing each to fill space?) It would take 1/2-hour to try your "spawn 100+" idea (and why not test with overlapSphere before placing?) You aren't going to use up your computer's weekly cylinder quota.
Once you get more and more into it, and understood the various issues (is it extra important to avoid gaps on the edge, to make sure the whole thing looks round? ...) Then you'd probably go back to the StackOverflow answers you got and they would make a lot more sense.
Thanks again, Owen. I don't know how to make it much clearer, but I'll try my best.
do you need three exact sizes, or would you be happy with shrinking/growing each to fill space?
I don't $$anonymous$$d scaling each to fill space, so long as they're within a defined range.
One method I've thought of is instantiating a circle at a random point in the circle, then instantiating each circle thereafter the maximum distance from the existing circle(s), until there is no possible spaces (the $$anonymous$$imum distance cannot be reached). That way, the circles would form the shape of a larger one.
I think this would work, but again, I don't know where to begin. I guess my question then is how to instantiate an object the maximum possible distance (within a circle) away from the existing ones.
The end result I'm after is something like this:
Answer by Kiloblargh · Feb 03, 2014 at 09:20 AM
Just instantiate them all randomly, but then for each circle, get a list of transforms of the other circles that are within a certain distance. Then loop through each and apply a repelling force away from the circle inversely proportional to the distance if the distance is too close, and an attracting force toward it directionally proportional to the distance if the distance is too far. Keep doing it every frame and they will settle into a stable pattern within a few seconds.
( That approach will work perfectly for the number and density of circles you posted in your screen shot; to do it for as many as the color vision test in your original post, not so much. )
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Help with Generating Random Tiles 1 Answer
Changing Objects Material Using My Array 1 Answer
Randomly Generated Levels 3 Answers