0

I want to get a random point in the red circle, and escaping the blue circle :

enter image description here

I made this:

double r = radius * Math.sqrt(R.nextDouble());
double theta = R.nextDouble() * 2 * Math.PI;
int x = (int) (r * Math.cos(theta));
int z = (int) (r * Math.sin(theta));

But it only find in red circle.

So, I tried to add something when X or Z are below the blue's circle radius, but I get this result :

enter image description here

I also tried to upgrade X or Z when distance between the random point and the center (which is 0/0) are too near.

I also made this snippet which test lot of X/Z position, but it will try everytimes. It's clearly not optimized because I have to filter all generated values, instead of directly generate values in required range.

function getNumberIn(min, max) {
   return Math.random() * (max - min) + min;
}

var canvas = document.getElementById("circlecanvas");
var context = canvas.getContext("2d");
context.beginPath();
context.arc(150, 150, 150, 0, Math.PI * 2, false);
context.fillStyle = "yellow";
context.fill();
context.closePath();

context.beginPath();
context.arc(150, 150, 50, 0, Math.PI * 2, false);
context.fillStyle = "red";
context.fill();
context.closePath();

context.fillStyle = "black";

let nb = 0;
for (let i = 0; i < 1000; i++) {
  let x = getNumberIn(0, 300);
  let z = getNumberIn(0, 300);
  
  let distance = Math.sqrt((x - 150) * (x - 150) + (z - 150) * (z - 150));
  if ((distance >= 50 || distance <= -50) && !(distance >= 150 || distance <= -150)) {
    context.fillRect(x, z, 3, 3);
  } else {
    nb++;
  }
}
console.log("Amount of skipped values: " + nb);
<canvas id="circlecanvas" width="300" height="300"></canvas>

How can I get random point in the red circle, excluding the blue one ?

Elikill58
  • 4,050
  • 24
  • 23
  • 45
  • Does this answer your question? [Generate a random point within a circle (uniformly)](https://stackoverflow.com/questions/5837572/generate-a-random-point-within-a-circle-uniformly) Just limit your range of valid radii to the range [blue_radius, red_radius] instead of [0, red_radius]. – 0x5453 Dec 14 '21 at 18:56
  • No @0x5453 , I mention the code from this and I wrote this code in my question – Elikill58 Dec 14 '21 at 19:03
  • This shape is called a ring. –  Dec 14 '21 at 19:19
  • What distribution should your random points follow ? –  Dec 14 '21 at 19:20
  • @YvesDaoust what do you mean with "distribution" ? – Elikill58 Dec 14 '21 at 19:20
  • Don't you work with random variables ? https://en.wikipedia.org/wiki/Probability_distribution –  Dec 14 '21 at 19:22
  • @YvesDaoust Yes I work with random variables, I want a random position in the circle – Elikill58 Dec 14 '21 at 19:24
  • So, what is the distribution ? –  Dec 14 '21 at 19:52
  • @YvesDaoust If I well understand, it's a uniform distribution. It's the `Random.nextInt` java's function – Elikill58 Dec 14 '21 at 20:09
  • This is the distribution of the generator uniform in an interval. Not the distribution of your 2D points. Do you confirm uniform in a ring ? –  Dec 14 '21 at 20:30

1 Answers1

2

Do the next change:

double r = Math.sqrt(
                     r_small*r_small + 
                     R.nextDouble() * (r_large*r_large-r_small*r_small));
//next lines remain the same 
double theta = R.nextDouble() * 2 * Math.PI;
int x = (int) (r * Math.cos(theta));
int z = (int) (r * Math.sin(theta));

where r_small is blue radius and r_large is outer radius of the red ring

This approach provides proper minimal and maximal distances and uniform distribution of points in the red ring.

MBo
  • 77,366
  • 5
  • 53
  • 86