Rachel_1988
Rachel_1988

Reputation: 45

How can I get a random x and y coordinate inside a circle radius?

I figured I'd use rand() to get a number between 0 and 20000 twice to get a random x and y coordinate. This works but it gives me random coordinates from within a square.

What I really need is coordinates within a circle. How can I limit my random x/y to within a circle which has a radius of 20,000?

I've tried a few sample codes online but most of those seem to be for computing spheres and finding the distance between two points on a sphere and I'm not knowledgeable enough to apply those to my usage of just picking a random coordinate within a circle (flat) radius.

Any help would be greatly appreciated.

Upvotes: 3

Views: 2478

Answers (3)

jeroen
jeroen

Reputation: 91734

You can get a random x between -20,000 and 20,000 and use Pythagoras law to get the positive y value. Then you do a random 0 or 1 to make that value positive or negative.

An example:

$r = 20000;
$x = rand(-$r, $r);
$y = rand(0, 1) ? -sqrt(pow($r, 2) - pow($x, 2)) : sqrt(pow($r, 2) - pow($x, 2));
var_dump($x, $y);

I am not sure how the numbers are distributed exactly but it sounds about right.

Edit: Thanks @andand, of course this calculates points on the circle only. To get points anywhere in the circle, the calculated y value is the maximum:

$r = 20000;
$x = rand(-$r, $r);
$yMax = sqrt(pow($r, 2) - pow($x, 2));
$y = rand(-$yMax, $yMax);
var_dump($x, $y);

Upvotes: 1

MBo
MBo

Reputation: 80177

To generate uniform distributed random points inside the circle of radius R, you can use the next approach:

a = Random  //range 0..1
b = Random  
theta = b * 2 * Pi
rr = R * Sqrt(a)
x = rr * Cos(theta)
y = rr * Sin(theta)

Upvotes: 3

iainn
iainn

Reputation: 17417

Generalised function to return a random point within a circle:

/**
 * @param $radius integer
 * @return array['x', 'y']
 */
function getPoint($radius)
{
    $i = mt_rand() / mt_getrandmax();
    $j = mt_rand() / mt_getrandmax();

    $w = $radius * sqrt($i);
    $theta = (2 * pi() * $j);
    $x = $radius + ($w * cos($theta));
    $y = $radius + ($w * sin($theta));

    return compact('x', 'y');
}

Bonus implementation in GD:

$radius = 250;

$image = imagecreatetruecolor((2 * $radius) + 1, (2 * $radius) + 1);
$white = imagecolorallocate($image, 255, 255, 255);
$black = imagecolorallocate($image, 0,   0,   0);

imagefill($image, 0, 0, $white);
imageellipse($image, $radius, $radius, $radius * 2, $radius * 2, $black);

for ($a = 0; $a < 1000; $a++)
{
    $point = getPoint($radius);
    imagesetpixel($image, $point['x'], $point['y'], $black);
}

// Output the image.
header("Content-type: image/png");
imagepng($image);

Upvotes: 2

Related Questions