# Calculate random points (pixel) within a circle (image)

I have an image that contains a circles at a specific location, and of a specific diameter. What I need to do is to be able to calculate random points within the circle, and then manipulate the pixels said points correlate to. I have the following code already:

``````private Point CalculatePoint()
{
var angle = _random.NextDouble() * ( Math.PI * 2 );
var x = _originX + ( _radius * Math.Cos( angle ) );
var y = _originY + ( _radius * Math.Sin( angle ) );
return new Point( ( int )x, ( int )y );
}
``````

And that works fine for finding all the points at the circumference of the circle, but I need all points from anywhere in the circle. If this doesn't make sense let me know and I will do my best to clarify.

-
Check the update. – David Gouveia Apr 3 '12 at 20:34
Good question in the sense that inadvertently creating a weighted distribution is a common error. – Tim Holt Apr 3 '12 at 20:54

If you want a simple solution just randomize the radius too:

``````private Point CalculatePoint()
{
var angle = _random.NextDouble() * Math.PI * 2;
var x = _originX + radius * Math.Cos(angle);
var y = _originY + radius * Math.Sin(angle);
return new Point((int)x,(int)y);
}
``````

That however results in your points being more concentrated towards the center of the circle:

In order to get an uniform distribution make the following change to the algorithm:

``````var radius = Math.Sqrt(_random.NextDouble()) * _radius;
``````

Which will give the following result:

For more information check the following link: MathWorld - Disk Point Picking.

And finally here's a simple JsFiddle demonstration comparing both version of the algorithm.

-
Excellent answer. Just one thing to add: don't forget to seed the random number generator :) – ktodisco Apr 3 '12 at 20:40
Oop you beat met to it - didn't see this post when I posted mine. The wolfram site is an awesome resource for this kind of thing. – Tim Holt Apr 3 '12 at 20:54
@TimHolt Happens all the time :) – David Gouveia Apr 3 '12 at 21:05
Is this assuming the circle center is at 0,0 ? – jjxtra Sep 29 '13 at 18:06
@PsychoDad The center of the circle would be (_originX, _originY) – David Gouveia Oct 1 '13 at 10:12

You’re halfway there. In addition to generating a random angle, just generate a random distance, less than or equal to the radius:

``````private Point CalculatePoint()
{
var angle = _random.NextDouble() * Math.PI * 2;
var distance = _random.NextDouble() * _radius;

var x = _originX + (distance * Math.Cos(angle));
var y = _originY + (distance * Math.Sin(angle));
return new Point((int)x, (int)y);
}
``````

Now you’re thinking with polar.

-
Okay, so we gave exactly the same answer within seconds of difference. Now what? :) – David Gouveia Apr 3 '12 at 20:23
@DavidGouveia We both get upvotes for both being right. Everybody wins! :D – Jon Purdy Apr 3 '12 at 20:24
Both answers very much appreciated (and the link too!). Man I am an idiot for not seeing that myself though, -1 to me :( Thanks again to you both! – DMills Apr 3 '12 at 20:29

DO NOT just use random r and theta! This creates a weighted distribution with more points in the center. This page illustrates it well...

http://mathworld.wolfram.com/DiskPointPicking.html

Here's the method that creates a non-weighted distribution...

``````var r = rand(0,1)
var theta = rand(0,360)

var x = sqrt(r) * cos(theta)
var y = sqrt(r) * sin(theta)
``````
-
Oops duplicate of selected answer :P – Tim Holt Apr 3 '12 at 20:56

If performance is an issue then one alternative solution is to generate a random position in a box with the width/height of your circle and then throw away any points that are not in the area of the circle.

The advantage of this method is that you are doing no cos/sin/sqrt functions, which depending on your platform may be a big speed saving.

``````var x = _random.NextDouble();
var y = _random.NextDouble();
if (x*x + y*y < 1.0f)
{
// we have a usable point inside a circle
x = x * diameter - _radius + _OriginX;
y = y * diameter - _radius + _OriginY;
// use the point(x,y)
}
``````
-
I'm going to try that out and see if it speeds things up. I'm not sure I have a performance problem, but I'll try this anyway, thanks! – DMills Apr 11 '12 at 1:51