I'm not sure if this is better than reject sampling, but here is a solution for uniformly sampling a circle segment (with a central angle <= pi) using a numerical calculation of the inverse function. (A single sample of the intersection of two circles can then be composed of a sample of segments, sectors, and triangles, depending on how the intersection can be divided into simpler shapes.)
First, we need to know how to create a random value Z with a given distribution F , that is, we want
P(Z < x) = F(x) <=> (x = F^-1(y)) P(Z < F^-1(y)) = F(F^-1(y)) = y <=> (F is monotonous) P(F(Z) < y) = y
This means: if Z has the requested distribution F , then F(Z) is evenly distributed. Another way:
Z = F^-1(Y),
where Y evenly distributed over [0,1] , has the requested distribution.
If F has the form
/ 0, x < a F(x) = | (F0(x)-F0(a)) / (F0(b)-F0(a)), a <= x <= b \ 1, b < x
then we can choose a Y0 uniformly in [F(a),F(b)] and set Z = F0^-1(Y0) .
We choose the parameterization of the segment at (theta,r) , where the central angle of theta is measured on one side of the segment. When the center angle of the segment is alpha , the area of the segment intersects with the sector of the angle theta , starting at the beginning of the segment (for the unit circle theta in [0,alpha/2] )
F0_theta(theta) = 0.5*(theta - d*(s - d*tan(alpha/2-theta)))
where s = AB/2 = sin(alpha/2) and d = dist(M,AB) = cos(alpha/2) (the distance from the center of the circle to the segment). (The case alpha/2 <= theta <= alpha symmetric and is not considered here.) We need a random theta with P(theta < x) = F_theta(x) . The inverse to F_theta cannot be calculated symbolically - it must be determined by some optimization algorithm (for example, Newton-Raphson).
Once theta fixed, we need a random radius r in the range
[r_min, 1], r_min = d/cos(alpha/2-theta).
For x in [0, 1-r_min] distribution should be
F0_r(x) = (x+r_min)^2 - r_min^2 = x^2 + 2*x*r_min.
Here the inverse can be calculated symbolically:
F0_r^-1(y) = -r_min + sqrt(r_min^2+y)
Here is a Python implementation to prove the concept:
from math import sin,cos,tan,sqrt from scipy.optimize import newton
The visualization, apparently, checks the uniform distribution (of the upper half of the segment with the central angle pi/2 ):
import matplotlib.pyplot as plot segmentPoints = [randomPointInSegmentHalf(pi/2) for _ in range(500)] plot.scatter(*zip(*segmentPoints)) plot.show()
