Jump to content
  • Advertisement
Sign in to follow this  
Durakken

Random Circles in a Circle

This topic is 896 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

So I basically want to create 5 sizes of circles randomly generated and placed in a circle around a point (the radius being 500 units) and I want to do this with javascript and jpgs.

 

Normally what I'd do is create a table and then just randomly fill it with imgs of say 5px, but the differing sizes are giving me a problem on how to solve this, because if I create a table of 5px imgs 200 cells wide & high and have the sizes represented in colors I know I would get overlap which I don't want.

 

Another solution that doesn't sound so good would be to instead of printing right to the web page put the 5px chunks in an array and then when I come across a size that takes up multiple cells add the chunks in the other rows, and then when I come to those columns in the array have it detect and jump over them, but that seems a bit of a mess.

 

Another possible idea that I just thought of is set a number of circles to be generated.

Generate the circle sizes.

Then for each size place the chunks in the cells.

check if cell and surrounding cells are filled

If a cell is filled with a circle chunk already, re-roll until the piece is placed...

 

Though thinking that through it comes to mind that that might generate the problem of never being able to find a place to fill and then going into an infinite loop

 

Is there a better solution than any of those?

Share this post


Link to post
Share on other sites
Advertisement

It's not clear to me what you're trying to do, could you elaborate on what problem you're trying to solve?

Share this post


Link to post
Share on other sites

I want to produce an image that is 1000x1000 px wide

Inside this image I want there to be a circular area with a 1000px diameter

Inside this area I want around 4000 (current working number) shapes with widths of 5px, 10px, 20px, 40px, and 80px and each of these circles being at least 10px away from any other shape, though I'm primarily thinking of circles, squares, and hexes...though the different shapes aren't that important.

Also I want the center to be empty as well (i don't know how large the center is currently. I need to see how this looks before i decide and adjust it)

Also I need to be able adjust the frequency of those sizes and edit the color of the circles to indicate anothe attribute. (For example a 5px circle can be red, blue, green, orange, etc, based another attribute that i can change the frequency of)

 

This sounds completely wierd, but that's what I need.

I don't think what it is for is important so I'll leave that out, but it's just the first step in what I'm doing.

Share this post


Link to post
Share on other sites

Ok I figured out a bunch of how to do this...

 

Create the first circle with x/y coordinate, and size. Throw it in an Array

With each new circle test it against the whole array

If the circle fails reroll, if it passes add it to the array

When the Array has x number of members draw all the circles

 

To create the circles i'll use canvas

And for the check, this tut seems perfect for what i need. http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769

 

The only problem I think I now have (besides brain not working right right now problems which is why I'm not writing all that up right this second) is that I want all these circles to be within a certain radius of the center... I think I could use that tutorial and reverse the detection to see if the circle is inside another circle, but I'm not sure.

Share this post


Link to post
Share on other sites

Sounds like you need something like a Poisson disc sample set: https://www.jasondavies.com/poisson-disc/

 

This can be used to distribute sample points with a minimal distance within a boundary.

 

Mitchell's Best Candidate algorithm might also work well: http://bl.ocks.org/mbostock/1893974

 

The first link I can't find the sample... but both the first and second aren't doing quite what I want and the code on the second one I don't feel like figuring out ^.^ for something that seems to be doing something different than what i want, but similar... but different enough to not quite useful.

 

Thanks though...those scripts look interesting.

Share this post


Link to post
Share on other sites

The only problem I think I now have (besides brain not working right right now problems which is why I'm not writing all that up right this second) is that I want all these circles to be within a certain radius of the center... I think I could use that tutorial and reverse the detection to see if the circle is inside another circle, but I'm not sure.

 

Just generate by angle/radius instead of x/y:

angle = random(0, PI*2)
distanceFromCenter = random(minimalDistanceFromCenter + newCircleRadius, maximalDistanceFromCenter - newCircleRadius)
newCirclePositionX = centerX + cos(angle) * distanceFromCenter
newCirclePositionY = centerY + sin(angle) * distanceFromCenter

Share this post


Link to post
Share on other sites

Here's what I got so far...

The multidimensional array after the do while loop seems to be messing up and I don't know why.

-----

edit: got some help in the chat... fixed it a little bit, now it gets to 4th itteration and then breaks at the same spot rather than not going through even once.

edit2: Figured out the array thing... now the overlapCheck function isn't working...

<html>
<body>
<canvas id="myCanvas" width="1000" height="1000" style="border:3px solid #c3c3c3;">
It appears that your browser does not support HTML5 and the canvas element.
</canvas>

<script type="text/javascript">
function drawCircle(x,y,r,color) {
    color.beginPath();
    color.arc(x,y,r,0,Math.PI*2,true);
    color.closePath();
    color.fill();
}

function getColor() {
var hexColor = "#000000";
return hexColor.toUpperCase();
}


function overlapCheck(x,y,radius) {
for(var i=1; i<4000; i++) {

if (x + radius + Circle[i][2] > Circle[i][0] 
&& x < Circle[i][0] + radius + Circle[i][2]
&& y + radius + Circle[i][2] > Circle[i][1] 
&& y < Circle[i][1] + radius + Circle[i][2])
{
//AABBs are overlapping

distance = Math.sqrt(
            ((x - Circle[i][0]) * (x – Circle[i][0]))
          + ((y - Circle[i][1]) * (y – Circle[i][1]))
);

if (distance < radius + Circle[i][2]) {
pass = false;
} else { 
pass = true;}
}

return pass;
}
}


//Construct Array and first entry
var Circle = [];
for (var i=0;i<4000;i++) {
     Circle[i] = [,,,];
}

Circle[0][0] = 500;
Circle[0][1] = 500;
Circle[0][2] = 50;
Circle[0][3] = "#000000";

// Fill Array
for(var i=1; i<10; i++) {
do {
var x = Math.floor((Math.random() * 1000));
var y = Math.floor((Math.random() * 1000));
var radsize = Math.floor((Math.random() * 5) + 1);
if(radsize == 1) {radius = 2.5;}
if(radsize == 2) {radius = 5;}
if(radsize == 3) {radius = 10;}
if(radsize == 4) {radius = 20;}
if(radsize == 5) {radius = 40;}

//var pass = overlapCheck(x,y,radius);
pass = true
}
while(pass == false)
/*
while loop check variable = !overlapCheck(x,y,radius)
Current variable is just to bypass
*/
Circle[i][0] = x;
Circle[i][1] = y;
Circle[i][2] = radius;
Circle[i][3] = "#000000";

}

var theCanvas=document.getElementById("myCanvas");
var canvasContext=theCanvas.getContext("2d");

circles = Circle.length;
for(var i=0; i<circles; i++) {
canvasContext.fillStyle=Circle[i][3];
drawCircle(Circle[i][0],Circle[i][1],Circle[i][2],canvasContext);
}
</script>
</body>
</html>
Edited by Durakken

Share this post


Link to post
Share on other sites
Rewritten. Though none of the circles move.
 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>


</head>
<body>


    <canvas id="myCanvas" width="1000" height="1000" style="border:3px solid #c3c3c3;">
    It appears that your browser does not support HTML5 and the canvas element.
    </canvas>

    <script type="text/javascript">
        function drawCircle(x, y, r, color) {
            color.beginPath();
            color.arc(x, y, r, 0, Math.PI * 2, true);
            color.closePath();
            color.fill();
        }

        function getColor() {
            var hexColor = "#000000";
            return hexColor.toUpperCase();
        }


        function overlapCheck(x, y, radius) {
            var pass = false; // not sure of the initial value
            for (var i = 1; i < 4000; i++) {

                if (
                    ((x + radius + Circle[i][2]) > Circle[i][0])
                    &&
                     (x < (Circle[i][0] + radius + Circle[i][2]))
                    &&
                     ((y + radius + Circle[i][2]) > Circle[i][1])
                    &&
                     (y < (Circle[i][1] + radius + Circle[i][2]))
                   ) {
                    //AABBs are overlapping

                    var x_circle = (x - Circle[i][0]);
                    var y_circle = (y - Circle[i][1]);
                    distance = Math.sqrt((x_circle * x_circle) + (y_circle * y_circle));

                    if (distance < radius + Circle[i][2]) {
                        pass = false;
                    } else {
                        pass = true;
                    }
                }

                return pass;
            }
        }


        //Construct Array and first entry
        var Circle = [];
        for (var i = 0; i < 4000; i++) {
            Circle[i] = [, , , ];
        }

        Circle[0][0] = 500;
        Circle[0][1] = 500;
        Circle[0][2] = 50;
        Circle[0][3] = "#000000";

        // Fill Array
        for (var i = 1; i < 10; i++) {
            do {
                var x = Math.floor((Math.random() * 1000));
                var y = Math.floor((Math.random() * 1000));
                var radsize = Math.floor((Math.random() * 5) + 1);
                if (radsize == 1) { radius = 2.5; }
                if (radsize == 2) { radius = 5; }
                if (radsize == 3) { radius = 10; }
                if (radsize == 4) { radius = 20; }
                if (radsize == 5) { radius = 40; }

                var pass = overlapCheck(x,y,radius);
                //pass = true
            }
            while (pass == false)
            /*
            while loop check variable = !overlapCheck(x,y,radius)
            Current variable is just to bypass
            */
            Circle[i][0] = x;
            Circle[i][1] = y;
            Circle[i][2] = radius;
            Circle[i][3] = "#000000";

        }

        var theCanvas = document.getElementById("myCanvas");
        var canvasContext = theCanvas.getContext("2d");

        circles = Circle.length;
        for (var i = 0; i < circles; i++) {
            canvasContext.fillStyle = Circle[i][3];
            drawCircle(Circle[i][0], Circle[i][1], Circle[i][2], canvasContext);
        }
    </script>     
</body>
</html>
Edited by Alpheus

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!