Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populating a circle with dots, using bias towards the edge of the cirlcle

This is what I am trying to achieve

example of dot circle with bias towards edges

So far I am happy with the code I have, borrowing from Wolfram and another source for some maths.

But I can't figure out how to integrate some bias calculation, or simply a method to distribute what will be random, but kind of organised!

Can anyone point me in the right direction?

Here's my code, which will run in browser using P5

var numDots = 3000;
var dotSize = 1.5;
var dotCoordinates = [];
var randomHue;
var xoff = 0;
var fps = 30;

function setup() {
  createCanvas(600,600);
  ellipseMode(CENTER);
  colorMode(HSB,360,100,100);
  randomHue = random(360);
  frameRate(fps);

  for(i=0; i < numDots; i++) {
    var rnd = map(noise(xoff),0,1,0,width);
    var R = 300; //circle radius
    var a = random(rnd) * TWO_PI; //random angle

    // var r = R * noise(rnd); 					// donuts
    // var r = R * noise(random()); 		// dust rings
    // var r = R * random(noise(rnd)); 	// starburst
    var r = R*0.6 * sqrt(random()); 		// solid

    var x = width/2 + r * cos(a);
    var y = height/2 + r * sin(a);  
    result = createVector(x,y);
    dotCoordinates.push(result);
    xoff += 0.001;
  }    

}

function draw() {
  background(randomHue,100,10);
  noStroke();

  for(i=0; i < dotCoordinates.length; i++) {  
    fill(randomHue,50,80);
    ellipse(dotCoordinates[i]['x'], dotCoordinates[i]['y'], dotSize, dotSize);
  }

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
like image 451
matski Avatar asked Oct 15 '25 09:10

matski


1 Answers

What you are trying to do reminds me of the Poincare disk model. What you can do is randomly pick a hyperbolic distance, h, of the point from the center of the disc and then use the conversion r = tanh(h/2) to convert it to the Euclidean distance from the center. Proof of concept:

function setup() {
  createCanvas(250, 250);
  background(0);
  noStroke();
  fill(255);
  noLoop();
}

function draw() {
  translate(width / 2, height / 2);
  for (let i = 0; i < 5000; i++) {
    let theta = random(0, TWO_PI);
    let h = randomGaussian(3.3); //experiment with different means
    let r = (exp(h) - 1) / (exp(h) + 1);
    let x = width / 2 * r * cos(theta);
    let y = height / 2 * r * sin(theta);
    ellipse(x,y,1,1); 
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js"></script>

Typical output is illustrated below. You can try different means and standard deviations (other than the default 1) in the call to randomGaussian() to tweak the appearance.

enter image description here

like image 147
John Coleman Avatar answered Oct 19 '25 01:10

John Coleman