Polar integration seems to be the best method for creating a general formula for this.
Re-expressing both circles as polar yields this:
$r1 = 1$ and $r2 = cos\theta+\sqrt(a^2-sin^2\theta)$ based off of the general formula for a polar circle, centered at $(1, 0)$ with radius $a$. Really all we need here are the points of intersection which can easily be solved by setting each equation equal and following algebraic and trigonometric rules
$$cos\theta+\sqrt(a^2-sin^2\theta) = 1$$
$$a^2-sin^2\theta=1+cos^2\theta-2cos\theta$$
Replacing $sin^2$ and $cos^2$ with 1 and solving for theta yields:
$$\theta=\pm arcos(a^2-2/-2)$$
From here it should be noted that we must add $\pi$ to the resulting angle because our result accounts for the part of the circle outside of the central unit circle. So our angles from which we base our integral are
$$\theta = \pi \pm arcos(a^2-2/-2)$$
At this point I believe you can evaluate this regularly
$$.5\int_{\theta_1}^{\theta_2} 1^2-[cos\theta+\sqrt({a^2-sin^2\theta})]^2 \,d\theta$$
There may be some errors I missed in my answer however this general method should work
Let $R_g$ be the radius of the green circumcircle, $R_b$ be the radius of the single blue circle, and there be $n \ge 1$ red circles. We wish to solve $\theta_r$, the angle between centers of each pair of consecutive red circles, and $R_r$, the radius of each of the red circles.
The radius of the centers of the red circles must be $R_g - R_b$. If we use a coordinate system where the origin is at the center of the green circle, the center of the blue circle is at $(R_b-R_g, 0)$.
If $n = 1$, then the one red circle has radius $R_r = R_g - R_b$ and is centered at $(R_b, 0)$.
If $n = 2$, then the two red circles have radius $R_r$ centered at $(x, \pm y)$,
$$\left\lbrace\begin{aligned}
R_r &= \displaystyle \frac{4 R_g R_b (R_g - R_b)}{(R_g + R_b)^2 } \\
x &= \displaystyle \frac{R_g ( 3 R_b - R_g )}{R_g + R_b} \\
y &= R_r \\
\theta_r &= 2 \operatorname{atan2}(y, x) = 2 \arctan\left(\frac{4 R_b (R_g - R_b)}{(3 R_b - R_g)(R_b + R_g)}\right)\\
\end{aligned}\right.$$
For $n \ge 3$, we need to solve
$$\cos\left((n-1)\frac{\theta_r}{2}\right) - \frac{2 R_b}{R_g - R_b}\sin\left(\frac{\theta_r}{2}\right) + 1 = 0$$
for $\theta_r$; then $$R_r = \displaystyle R_g \frac{\sin\left(\frac{\theta_r}{2}\right)}{1 + \sin\left(\frac{\theta_r}{2}\right)}$$
I recommend using a binary search in range $$0 \le \theta_r \le \frac{2 \pi}{n}$$as there is only one zero for $$f(\theta_r) = \cos\left((n-1)\frac{\theta_r}{2}\right) - \frac{2 R_b}{R_g - R_b}\sin\left(\frac{\theta_r}{2}\right) + 1$$ If $f(\theta_r) \lt 0$, $\theta_r$ is too large; if $f(\theta_r) \gt 0$, $\theta_r$ is too small.
(The upper limit applies if $R_b = 0$, as then the red circles form a closed ring of circles.)
For neighboring red circles to touch, $$R_r = (R_g - R_r) \sin\left(\frac{\theta_r}{2}\right) \quad \iff \quad R_r = R_g \frac{\sin(\theta_r/2)}{1 + \sin(\theta_r/2)}$$
Here is a verified Python implementation, that returns $R_r$ and $\theta_r$ as a tuple:
from math import pi, atan2, sin, cos
def find_r_theta(rG, rB, n):
n = round(n)
if n < 1:
raise ValueError("N must be at least 1, %s given" % n)
if n == 1:
return (rG - rB, 0)
if n == 2:
rR = 4*rG*rB*(rG-rB)/(rG+rB)**2
return (rR, 2*atan2(rR, rG*(3*rB-rG)/(rG+rB)))
theta_max = 2*pi/n
theta_min = 0
ct = 0.5*(n-1)
cs = 2.0*rB / (rG - rB)
# 53 bits of precision
for k in range(0, 53):
theta = 0.5*(theta_min + theta_max)
d = cos(ct*theta) - cs*sin(0.5*theta) + 1
if d > 0.0:
theta_min = theta
elif d < 0.0:
theta_max = theta
else:
break
s = sin(0.5*theta)
rR = rG*s/(s+1)
# Abort if the blue radius is smaller than the red
if rB < rR:
raise ValueError("Blue radius (%f) smaller than the red radius (%d)" % (rB, rR))
return (rG*s/(s+1), theta)
If you add the following code, you can run it via python3 this.py rG rB N out.svg
, specifying the green circle radius, blue circle radius, and the number of red circles, and it'll create an SVG image, out.svg
, for illustration and verification; you can view those in any browser.
if __name__ == '__main__':
from sys import argv, stdout, stderr, exit
from math import ceil
if len(argv) < 4 or len(argv) > 5:
stderr.write("\n")
stderr.write("Usage: %s [ -h | --help ]\n" % argv[0])
stderr.write(" %s GREEN-RADIUS BLUE-RADIUS RED-CIRCLE-COUNT [ OUT.SVG ]\n" % argv[0])
stderr.write("\n")
exit(1)
rG = float(argv[1])
rB = float(argv[2])
n = round(float(argv[3]))
if len(argv) > 4:
svg = open(argv[4], mode="w", encoding="UTF-8")
else:
svg = stdout
rR, theta = find_r_theta(rG, rB, n)
center = int(ceil(rG+2))
svg.write('<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n')
svg.write('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="0 0 %d %d">\n' % (2*center, 2*center))
svg.write('<rect x="0" y="0" width="%d" height="%d" fill="#ffffff" stroke="none" />\n' % (2*center, 2*center))
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#00cc00" />\n' % (center, center, rG))
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#0000ff" />\n' % (center-rG+rB, center, rB))
if (n & 1):
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#ff0000" />\n' % (center+rG-rR, center, rR))
for i in range(1, int((n+1)/2)):
a = i * theta
x = (rG - rR) * cos(a)
y = (rG - rR) * sin(a)
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#ff0000" />\n' % (center+x, center+y, rR))
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#ff0000" />\n' % (center+x, center-y, rR))
else:
for i in range(0, int(n/2)):
a = (i + 0.5) * theta
x = (rG - rR) * cos(a)
y = (rG - rR) * sin(a)
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#ff0000" />\n' % (center+x, center+y, rR))
svg.write('<circle cx="%.3f" cy="%.3f" r="%.3f" fill="none" stroke="#ff0000" />\n' % (center+x, center-y, rR))
svg.write('</svg>\n')
svg.flush()
if svg != stdout:
svg.close()
How did I find the solution for $n \ge 3$?
Consider the following illustration: The green circle is centered at origin, with radius $R_g$:
The blue circle has radius $R_b$ and is centered at $(R_b - R_g, 0)$. Note that its center $x$ coordinate is actually $c = -R_g + R_b$: blue radius in from the leftmost point on the green circle.
Angle $\theta$ forms an isosceles triangle, with sides $R_g - R_r$ and base $2 R_r$. If we split it into two right triangles, where the hypotenuse length is $R_g - R_r$, short side length is $R_r$, and the angle opposite the short side $\theta/2$. Thus,
$$\sin\left(\frac{\theta}{2}\right) = \frac{R_r}{R_g - R_r} \tag{1a}\label{G1a}$$
Solving this for $R_r$ yields
$$R_r = R_g \frac{\sin\left(\frac{\theta}{2}\right)}{1 + \sin\left(\frac{\theta}{2}\right)} \tag{1b}\label{G1b}$$
This means that the red circle radius $R_r$ is defined by $\theta$, and $\theta$ is our only free variable. And only positive $\theta$ make any sense.
If there was no blue circle at all, then the $n$ red circles would cover the full circle: $n \theta = 2 \pi$. This gives us the possible range for $\theta$,
$$0 \lt \theta \lt \frac{2 \pi}{n} \tag{2}\label{G2}$$
The topmost red circle is always at angle
$$\theta_T = \frac{(n - 1) \theta}{2}$$ counterclockwise from right. Its center is at $(x, y)$,
$$\left\lbrace \begin{aligned}
x = (R_g - R_r) \cos \theta_T &= (R_g - R_r) \cos\left(\frac{(n - 1) \theta}{2}\right) \\
y = (R_g - R_r) \sin \theta_T &= (R_g - R_r) \sin\left(\frac{(n - 1) \theta}{2}\right) \\
\end{aligned} \right. \tag{3a}\label{G3a}$$
For the topmost red circle and the blue circle to touch, we need the distance between their centers to match the sum of their radiuses. Squaring the distances, we have
$$(x - b)^2 + y^2 = (R_b + R_r)^2 \tag{3b}\label{G3b}$$
Next, we subtract the right side from the left side (so we get a function of form $f(\theta)$ whose root we need to find), substitute $x$, $y$, $b$, and $R_r$.
At this point, the expression starts to sprawl, and I for one switch to a Computer Algebra System. I suggest wxMaxima or SageMath; both free and available for all operating systems. In Maxima:
declare(R_g,real, R_b,real, R_r,real, theta,real, n,integer) $
R_r : R_g * sin(theta/2) / (1 + sin(theta/2)) $
x : (R_g - R_r) * cos((n-1)*theta/2) $
y : (R_g - R_r) * sin((n-1)*theta/2) $
b : -R_g + R_b $
EQ : (x-b)^2 + y^2 - (R_b + R_r)^2 = 0;
and after applying rational and trigonometric simplifications (trigsimp(ratsimp(EQ));
), we get
(((2*R_g^2-2*R_b*R_g)*sin(theta/2)+2*R_g^2-2*R_b*R_g)*cos((n-1)*theta/2)
+(2*R_g^2-6*R_b*R_g)*sin(theta/2)
+4*R_b*R_g*cos(theta/2)^2+2*R_g^2-6*R_b*R_g) / (2*sin(theta/2) - cos(theta/2)^2 + 2) = 0
That divisor, $2\sin(\theta/2) - \cos(\theta/2)^2 + 2 \ge 1$ in this context, because we only do this for $n \ge 3$ and therefore $0 \lt \theta/2 \lt \pi/3$, per $\eqref{G2}$. So, we can just omit it, by multiplying the equation with it. There is also a common factor $R_g$, which we can divide out at the same time: trigsimp(ratsimp(% * (2*sin(theta/2) - cos(theta/2)^2 + 2) / R_g));
and we get
((2*R_g-2*R_b)*sin(theta/2)+2*R_g-2*R_b)*cos((n-1)*theta/2)
+ (2*R_g-6*R_b)*sin(theta/2)
+ 4*R_b*cos(theta/2)^2
+ 2*R_g-6*R_b = 0
Replacing $\cos(\theta)^2$ with $1 - \sin(\theta)^2$, we have
((2*R_g-2*R_b)*sin(theta/2)+2*R_g-2*R_b)*cos((n-1)*theta/2)
+ (2*R_g-6*R_b)*sin(theta/2)
+ 4*R_b*(1 - sin(theta/2)^2)
+ 2*R_g-6*R_b = 0;
and finally, if we ask Maxima to solve this for $\theta$, solve(%, theta);
, it gives us two solutions:
[ theta = -%pi, cos((n-1)*theta/2) = -(2*R_b*sin(theta/2)-R_g+R_b)/(R_b-R_g) ]
The first one is garbage, so we grab the second one, cos((n-1)*theta/2) = -(2*R_b*sin(theta/2)-R_g+R_b)/(R_b-R_g);
, and subtract right hand side from left hand side to get a nice function form: ratsimp(lhs(%) - rhs(%)) = 0;
, so we get
((R_g-R_b)*cos((n-1)*theta/2) - 2*R_b*sin(theta/2) + R_g-R_b)/(R_g-R_b) = 0
i.e.
$$\frac{(R_g - R_b) \cos\left(\frac{(n-1) \theta}{2}\right) - 2 R_b \sin\left(\frac{\theta}{2}\right) + R_g - R_b }{R_g - R_b} = 0$$
or, equivalently
$$\cos\left(\frac{(n-1)\theta}{2}\right) - \frac{2 R_b}{R_g - R_b} \sin\left(\frac{\theta}{2}\right) + 1 = 0$$
Best Answer
You can write the equation of the line that goes through $A$ and $O$ as $$\frac{x-x_O}{x_A-x_O}=\frac{y-y_O}{y_A-y_O}$$ You know that $B$ is on this line, so $$\frac{x_B-x_O}{x_A-x_O}=\frac{y_B-y_O}{y_A-y_O}$$ So you have an equation with two unknowns, $x_B$ and $y_B$. The other equation is $$\frac{x_B-x_O}{x_A-x_O}=\frac{y_B-y_O}{y_A-y_O}=\frac{R_2}{R_1}$$ You can now solve the problem