Skip to main content
GameDev.net gamedev.net
🔒 Locked

Random point in a circle?

Started by jdarling Jul 18, 2005 at 9:00 AM 8 replies 16.8k views
Original Post
jdarling
jdarling
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
Ali_B
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,
HAM
HAM
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.
Ali_B
Ali_B
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..
ebnf
ebnf
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).

murali_13_99
murali_13_99
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);
_DarkWIng_
_DarkWIng_
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.
Ra
Ra
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
eq
eq
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;


jdarling
jdarling
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

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.