2

In python how to generate a random pair of points (x,y) that lies inside a circle of radius r.

Basically the x and y should satisfy the condition x^2 + y^2 = r^2.

FBruzzesi
  • 6,385
  • 3
  • 15
  • 37
Kaustubh Dwivedi
  • 418
  • 4
  • 16
  • Question is vague - `inside a circle of radius r` assumes x^2 + y^2 **<=** r^2. – MBo Apr 24 '20 at 05:49

2 Answers2

3

To generate uniformly distributed point inside origin-centered circle of radius r, you can generate two uniform values t,u in range 0..1 and use the next formula:

import math, random
r = 4
t = random.random()
u = random.random()
x = r * math.sqrt(t) * math.cos(2 * math.pi * u)
y = r * math.sqrt(t) * math.sin(2 * math.pi * u)
print (x,y)
MBo
  • 77,366
  • 5
  • 53
  • 86
  • What changes can be made such that x and y lie between the region of two concentric circles of radius r1 and r2. r1^2 <= x^2 + y^2 <= r2^2 – Kaustubh Dwivedi Apr 24 '20 at 06:45
  • @MBo I think `t` should be in range `Uniform[r1**2/r2**2, 1]` – FBruzzesi Apr 24 '20 at 11:12
  • For ring - generate value t in range (r1/r2)**2..1 with RandomUniform and use x = r2 * math.sqrt(t)... [Corresponding answer](https://stackoverflow.com/questions/41912170/trying-to-generate-random-x-y-coordinates-within-a-ring-in-python/41912356#41912356) – MBo Apr 24 '20 at 13:22
2

Using numpy to generate more than one point at a time:

import numpy as np 
import matplotlib.pyplot as plt 

n_samples = 1000

r = 4
# make a simple unit circle 
theta = np.linspace(0, 2*np.pi, n_samples)
a, b = r * np.cos(theta), r * np.sin(theta)

t = np.random.uniform(0, 1, size=n_samples)
u = np.random.uniform(0, 1, size=n_samples)

x = r*np.sqrt(t) * np.cos(2*np.pi*u)
y = r*np.sqrt(t) * np.sin(2*np.pi*u)

# Plotting
plt.figure(figsize=(7,7))
plt.plot(a, b, linestyle='-', linewidth=2, label='Circle', color='red')
plt.scatter(x, y, marker='o',  label='Samples')
plt.ylim([-r*1.5,r*1.5])
plt.xlim([-r*1.5,r*1.5])
plt.grid()
plt.legend(loc='upper right')
plt.show(block=True)

which results in:

enter image description here

FBruzzesi
  • 6,385
  • 3
  • 15
  • 37