I am wondering how i could generate random numbers that appear in a circular distribution.
I am able to generate random points in a rectangular distribution such that
I would use polar coordinates:
r_squared, theta = [random.randint(0,250000), 2*math.pi*random.random()]
Then r is always less than or equal to the radius, and theta always between 0 and 2*pi radians.
Since r is not at the origin, you will always convert it to a vector centered at 500, 500, if I understand correctly
x = 500 + math.sqrt(r_squared)*math.cos(theta)
y = 500 + math.sqrt(r_squared)*math.sin(theta)
Choose r_squared randomly because of this
import random
import math
# radius of the circle
circle_r = 10
# center of the circle (x, y)
circle_x = 5
circle_y = 7
# random angle
alpha = 2 * math.pi * random.random()
# random radius
r = circle_r * math.sqrt(random.random())
# calculating coordinates
x = r * math.cos(alpha) + circle_x
y = r * math.sin(alpha) + circle_y
print("Random point", (x, y))
In your example circle_x
is 500 as circle_y
is. circle_r
is 500.
Another version of calculating radius to get uniformly distributed points, based on this answer
u = random.random() + random.random()
r = circle_r * (2 - u if u > 1 else u)
FIRST ANSWER: An easy solution would be to do a check to see if the result satisfies your equation before proceeding.
Generate x, y (there are ways to randomize into a select range)
Check if ((x−500)^2 + (y−500)^2 < 250000) is true if not, regenerate.
The only downside would be inefficiency.
SECOND ANSWER:
OR, you could do something similar to riemann sums like for approximating integrals. Approximate your circle by dividing it up into many rectangles. (the more rectangles, the more accurate), and use your rectangle algorithm for each rectangle within your circle.
What you need is to sample from (polar form):
r, theta = [math.sqrt(random.randint(0,500))*math.sqrt(500), 2*math.pi*random.random()]
You can then transform r
and theta
back to cartesian coordinates x
and y
via
x = 500 + r * math.cos(theta)
y = 500 + r * math.sin(theta)
Related (although not Python), but gives the idea.
You can use rejection sampling, generate a random point within the (2r)×(2r)
square that covers the circle, repeat until get one point within the circle.
You can use below the code and if want to learn more https://programming.guide/random-point-within-circle.html
import random
import math
circle_x = 500
circle_y = 500
a = random.randint(0,500) * 2 * math.pi
r = 1 * math.sqrt(random.randint(0,500))
x = r * math.cos(a) + circle_x
y = r * math.sin(a) + circle_y