Random point in a circle?

Started by
8 comments, last by jdarling 18 years, 9 months ago
I know that this should be simple, but I'm having a brain fart... How do you find a random point inside of a circle? I basically want something like: POINT RandomCircle( POINT cSize ); Any ideas, faster would be better in this case as I'm using it for a spray can effect much like whats in MS-Paint. Thanks, Jeremy
Advertisement
x = r * cos (angle)
y = r * sin (angle)

All you have to do is specify the angle randomly!!

So Let's say the the circle itself is at coordinates (x1, y1) and you want to have a random point inside it, then:

x = x1 + r * cos (rand())
y = y1 + r * sin (rand())

where r is (of course) the radius of the circle.

regards,
Are you talking about INSIDE a circle?

You would need to know the center of the circle and the radius. Then just make sure the point is no farther away from the center than the radius.

If you are talknig about a point ON a circle then just do something like

R*cos(angle)+x
R*sin(angle)+y

Where R is the radius of the circle and x and y is the center point of the circle.
I'm sorry, that was for drawing points on the circles borders..

If you want them inside, then you have 2 situations

We said

x = x1 + r * cos (rand())
y = y1 + r * sin (rand())

After that, do the following:

if (x > x1)
x = x1 - (rand() % r)
else
x = x1 + (rand() % r)

if (y > y1)
y = y1 - (rand() % r)
else
y = y1 + (rand() % r)

That's a method.. I feel there is a much easier method, but my head is blocked to. Actually, my head was fed up with work, and so I joined GameDev to have some rest..
Quote:Original post by Ali_B
x = r * cos (angle)
y = r * sin (angle)

All you have to do is specify the angle randomly!!

So Let's say the the circle itself is at coordinates (x1, y1) and you want to have a random point inside it, then:

x = x1 + r * cos (rand())
y = y1 + r * sin (rand())

where r is (of course) the radius of the circle.

regards,


This will give a random point in the circle but the distribution will be more dense nearer the center of the circle.

One way to get a very uniform distribution is to sample randomly from a square centered on the circle's center and then test that the point is within the circle, if not try again.

As a speedup for your case you can precompute a collection of points that is the ratio of the square's area to the circle's area as the number of points you desire to have and then pick that many points and just ignore the ones that aren't chosen (this prevents the case that a very unlucky random number stream can cause this method to always pick a point outside the circle and never complete).

this should do it,

radius = random(); //between 0 and the radius of the circle
angle = random(); // between 0 and 360 (degrees)

x = center + radius*cos(angle);
y = center + radius*sin(angle);
Quote:Original post by murali_13_99
radius = random(); //between 0 and the radius of the circle
angle = random(); // between 0 and 360 (degrees)

x = center + radius*cos(angle);
y = center + radius*sin(angle);

Once again : uneven distribution.
You should never let your fears become the boundaries of your dreams.
Quote:Original post by jdarling
Any ideas, faster would be better in this case as I'm using it for a spray can effect much like whats in MS-Paint.
Quote:Original post by ebnf
This will give a random point in the circle but the distribution will be more dense nearer the center of the circle.

If you're using it for the airbrush, don't you want the distribution to be more dense near the center?
Ra
r = random value between 0 and 1
a = random value between 0 and 2*pi

float R = RealRadius - sqrt(r) * RealRadius; // Fix distribution and scale to [0, RealRadius]

float x = cosf(a) * R;
float y = sinf(a) * R;


Thanks everyone for your comments. After a bit of playing with the numbers I found the following to generate quite a nice look:

procedure TSprayCan.MouseHandler(X, Y: Integer; LeftButtonDown,
RightButtonDown: Boolean);
var
SpraySize : Integer;
AColor : TColor;
A, Xo, R,
Yo, Xp, Yp: Integer;
begin
if (LeftButtonDown or RightButtonDown) and
((LastX <> X) or (LastY <> Y)) then
begin
AColor := clBlack;
if LeftButtonDown then
AColor := LeftColor;
if RightButtonDown then
AColor := RightColor;

SpraySize := seSpraySize.Value;

Xo:=SpraySize Div 2;
Yo:=Xo;
R:=Yo;

For A:=0 to R Do
Begin
Xp :=Round(Random(R)*Sin(Random(360)/45));
Yp :=Round(Random(R)*Cos(Random(360)/45));

ImageSetPixel(XP + X, YP + Y, AColor);
End;

LastX := X;
LastY := Y;

ImageChanged;
end;
end;

Sorry but the source is in Delphi.

Jeremy

This topic is closed to new replies.

Advertisement