How do I create random dots concentrated in a particular area in JS?

2k Views Asked by At

Need some conceptual help here. Currently, I have a random-dot function that creates two sets of dots (orange and blue) that spread out over a canvas. But I'm looking for a way to concentrate the dot density in random areas around the screen.

The code looks essentially like this:

var createBlueDots = function () {
       for (var i = 0; i <=someRandomNum; i++) {
        context.beginPath();
        var rand_x = Math.random(i) * horz_max;
        var rand_y = Math.random(i) * vertical_max;
        context.arc(rand_x, rand_y, radius, 1, 2*Math.PI);
        context.fillStyle ="#0855A2";
        context.fill();
        context.closePath();   
        }
    }
createBlueDots();

... which when combined with another OrangeDot function creates something like this: image of random dots over a canvas

... but how do I create a series of dots that is concentrated around one or several areas of the screen? Something more like this?

concentrated dot area

Even just conceptual tips would be appreciated. Thank you.

1

There are 1 best solutions below

2
Hao Wu On BEST ANSWER

You can use an exponential function to determine the distance with some random angle to achieve this.

// dot count
const dots = 500;
// center point
const center = { x: 100, y: 100 };
// max distance from the center
const radius = 150;
// centripetal force, the larger it gets the more concentrated the dots are
const centripetal = 2.5;

const context = document.querySelector('canvas').getContext('2d');

var createBlueDots = function () {
 for (var i = 0; i <= dots; i++) {
  context.beginPath();
  const dist = (Math.random() ** centripetal) * radius;
  const angle = Math.random() * Math.PI * 2;
  var rand_x = dist * Math.cos(angle) + center.x;
  var rand_y = dist * Math.sin(angle) + center.y;
  context.arc(rand_x, rand_y, 2, 1, 2 * Math.PI);
  context.fillStyle = "#0855A2";
  context.fill();
  context.closePath();
 }
}

createBlueDots();
<canvas width="200" height="200"></canvas>