Function Repository Resource:

CircleInversion

Source Notebook

Compute the inversion of an object with respect to a reference circle in the Euclidean plane

Contributed by: Shenghui Yang (Wolfram Research)

ResourceFunction["CircleInversion"][circle,object]

yields the inversion of object with respect to the reference circle given the center and radius.

Details

The first argument must be of the form Circle[{x,y},radius].
The second argument can be any of the following objects: Line, InfiniteLine, Circle or Point. A list of two elements {x,y} that represents a 2D point is also supported.
The type of the result is dependent upon the object and whether it includes the center of inversion.
Inversion transforms the center of its reference circle to infinity and vice versa.

Examples

Basic Examples (2) 

Invert point P1={2,2} with respect to the reference unit circle to

In[1]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Point[{2, 2}]]
Out[1]=

This is the expected result from the power of a circle r2=12=OP1·OP2

In[2]:=
EuclideanDistance[{0, 0}, {2, 2}]*
  EuclideanDistance[{0, 0}, {1/4, 1/4}] == 1
Out[2]=

Invert a circle to another circle:

In[3]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Circle[{2, 2}, 1]] // Simplify
Out[3]=

Scope (2) 

CircleInversion works with arbitrary curves represented in parametric form for symbolic arguments. ParametricPlot can be used to visualize the transformed curve.

The inversion of a parabola is a cardioid if the center of inversion is the parabola's focus:

In[4]:=
p = 1/2;
parabola = {t^2, 2*p*t};
cardioid = Simplify[
  ResourceFunction["CircleInversion"][Circle[{p/2, 0}, 1], parabola], Assumptions -> t \[Element] Reals]
Out[4]=
In[5]:=
ParametricPlot[{cardioid[[1]], parabola}, {t, -4, 4},
 PlotRange -> {-4, 4}, Epilog -> {Dashed, Circle[{p/2, 0}, 1]}]
Out[5]=

The inversion of an equilateral hyperbola is a lemniscate of Bernoulli if the reference circle is centered on the bisector of the hyperbola's two foci:

In[6]:=
hyperbola = {Sec[t], Tan[t]}
Out[6]=
In[7]:=
lemniscate = Simplify[
  ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], hyperbola], Assumptions -> t \[Element] Reals]
Out[7]=
In[8]:=
ParametricPlot[{lemniscate[[1]], hyperbola}, {t, -\[Pi], \[Pi]}, PlotRange -> {-1.5, 1.5}, Epilog -> {Dashed, Circle[{0, 0}, 1]}]
Out[8]=

Applications (4) 

The inverse of a circle is another circle if the original circle does not contain the center of inversion:

In[9]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Circle[{2, 2}, 1]] // Simplify
Out[9]=

The inverse of a circle is a line if the original circle contains the center of inversion:

In[10]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Circle[{2, 2}, 2 Sqrt[2]]]
Out[10]=

The inverse of a line is a circle containing the center of inversion if the line does not contain the center:

In[11]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], InfiniteLine[{{1, 3}, {2, 4}}]]
Out[11]=

A line inverts to itself if it contains the center of inversion:

In[12]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], InfiniteLine[{{1, 1}, {2, 2}}]]
Out[12]=

Properties and Relations (3) 

CircleInversion is its own inverse:

In[13]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Point[{2, 2}]]
Out[13]=
In[14]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], %]
Out[14]=

Orthogonal circles are invariant under inversion with respect to each other. However, every point on each circle is inverted to a different place on the same circle (except for the intersection points):

In[15]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 3], Circle[{5, 0}, 4]]
Out[15]=
In[16]:=
ResourceFunction["CircleInversion"][Circle[{5, 0}, 4], Circle[{0, 0}, 3]]
Out[16]=

For instance, the point (red) is on the Circle[{0,0},3], which is inverted to the different location (blue) on the same circle:

In[17]:=
inverted = ResourceFunction["CircleInversion"][
   Circle[{5, 0}, 4], {-3/Sqrt[2], 3/Sqrt[2]}] // Simplify
Out[17]=
In[18]:=
With[{pts1 = {{5, 0}, {2, 6}, {(-3)/Sqrt[2], 3/Sqrt[2]}}, pts2 = {{(-3)/Sqrt[2], 3/Sqrt[2]}, {-5, -2}, 
Part[inverted, 1]}}, Graphics[{
Circle[{0, 0}, 3], 
Circle[{5, 0}, 4], {Red, 
PointSize[0.03], 
Point[{-(3/Sqrt[2]), 3/Sqrt[2]}]}, {Blue, 
PointSize[0.03], inverted}, {Dashed, 
InfiniteLine[{{5, 0}, {-(3/Sqrt[2]), 3/Sqrt[2]}}]}, {Dashed, Orange, 
Arrow[
BezierCurve[pts1]], 
Arrow[
BezierCurve[pts2]]}}, Axes -> True]]
Out[18]=

Its distance from the origin is still 3:

In[19]:=
Norm[inverted[[1]]] // FullSimplify
Out[19]=

Regardless of the different types of objects returned by this function, the result of CircleInversion is in general closed under a set of objects recognized by Graphics:

In[20]:=
Graphics[{{Dashed, Circle[{0, 0}, 1]},
  Circle[{1, 1}, 1 Sqrt[2]], ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Circle[{1, 1}, Sqrt[2]]]}]
Out[20]=

Possible Issues (4) 

The inverse of the center of the reference circle is defined as Infinity:

In[21]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Point[{0, 0}]]
Out[21]=

Conversely, the inverse of Infinity is the inversion center:

In[22]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], \[Infinity]]
Out[22]=

CircleInversion does not distinguish between Line and InfiniteLine in the second argument:

In[23]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], InfiniteLine[{{1, 1}, {2, 2}}]]
Out[23]=
In[24]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Line[{{1, 1}, {2, 2}}]]
Out[24]=

CircleInversion returns different results based on the syntax of InfiniteLine.

For an infinite line that goes through {3,1} and {1,0}, which does not include the inversion center, its image is a circle containing the inversion center:

In[25]:=
ResourceFunction["CircleInversion"][Circle[{1, 1}, 1], InfiniteLine[{{3, 1}, {1, 0}}]]
Out[25]=

For an infinite line that passes through {3,1} and is in the same direction as the vector {1,0} (a horizontal line that passes through the inversion center), its image is the line itself:

In[26]:=
ResourceFunction["CircleInversion"][Circle[{1, 1}, 1], InfiniteLine[{3, 1}, {1, 0}]]
Out[26]=

In general, the center of the original circle and that of its inversion are not inversion points with respect to each other:

In[27]:=
inv = ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], Circle[{3, 0}, 1/2]]
Out[27]=
In[28]:=
ResourceFunction["CircleInversion"][Circle[{0, 0}, 1], {3, 0}]
Out[28]=

The center of the image is the midpoint of the inversion of the antipodal points on the original circle:

In[29]:=
ResourceFunction["CircleInversion"][
   Circle[{0, 0}, 1], #] & /@ {{3 - 1/2, 0}, {3 + 1/2, 0}}
Out[29]=
In[30]:=
Midpoint[%][[1]] === inv[[1]]
Out[30]=

Neat Examples (3) 

Let three circles have a common point. Suppose that the common chord of two of them is a diameter of the third. If this is true for two of the three common chords, then you can prove it must be true for all three of them (C. S. Ogilvy, Excursions in Geometry).

Proof by inversion: Convert the diagram on the left to right, complete the proof with the concurrency of three altitudes in any triangle. The center of inversion is the concurrency of three circles.

Use Manipulate to see the invariance of the result by changing the configuration of the circles constrained by the statement of the problem:

In[31]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/d83e3fed-2173-44c9-a418-1a7fb7b38680"]
Out[32]=

Semicircles with centers at A (red) and B (blue) and with radii 2 and 1, respectively, are drawn in the interior of, and sharing bases with, a semicircle with diameter JK. The two smaller semicircles are externally tangent to each other and internally tangent to the largest semicircle (dashed). A circle centered at P is drawn externally tangent to the two smaller semicircles and internally tangent to the largest semicircle. What is the radius of the circle centered at P? (2017 AMC 12A Problem 16)

Here is the Arbelos and Chain of Pappus:

In[33]:=
attributes = {{Red, Thick}, {Blue}, {Black, Dashed}};
objList1 = MapThread[
   Append, {attributes, {Circle[{2, 0}, 2, {0, \[Pi]}], Circle[{5, 0}, 1, {0, \[Pi]}], Circle[{3, 0}, 3, {0, \[Pi]}]}}];
Graphics[objList1, Axes -> True, PlotRange -> {0, 3}]
Out[34]=

The result can be easily generalized to the nth circle in the chain by circle inversion. Choose the center of inversion to be {0,0} and let the radius of the reference circle be 6 ( marked by as the largest circle in the diagram at bottom):

In[35]:=
inverse2[obj_] := ResourceFunction["CircleInversion"][base, obj];
base = Circle[{0, 0}, 6]
Out[36]=

Find the radius of the first fifteen circles in the chain:

In[37]:=
n = 15;
imagebase = inverse2[Circle[{5, 0}, 1]]
Out[38]=
In[39]:=
circleList1 = Table[Circle[imagebase[[1]] + 2*{0, imagebase[[2]]*k}, imagebase[[2]]], {k, 1, n}]
Out[39]=
In[40]:=
ans = Simplify[(inverse2 /@ circleList1)[[All, 2]]]; 
ans[[1]] = Framed[ans[[1]]]
Out[40]=

The framed part is the answer to this problem. In the diagram below, each disk is the element in the chain of Pappus by inverting the circle with the same color from the column on the right:

In[41]:=
objList2 = MapThread[
   Append, {attributes, inverse2 /@ {Circle[{2, 0}, 2], Circle[{5, 0}, 1], Circle[{3, 0}, 3]}}];
disks = ((inverse2 /@ circleList1) // Simplify) /. Circle -> Disk;
hueList = {Hue[#], Opacity[0.9]} & /@ (Range[n]/n);
Graphics[
 objList1~Join~MapThread[Append, {hueList, disks}]~Join~objList2~Join~
  MapThread[Append, {hueList, circleList1}]~
  Join~{{RGBColor[0.46, 0.4, 1], Circle[{0, 0}, 6]}}, Axes -> True, PlotRange -> {{0, 9}, {-6, 9}}]
Out[42]=

The combination of inversion and a coaxial family (or pencil of circles) is the key step to finding the Steiner chain of two given non-intersecting circles. For 0<|t|<1, one has the points , B={t,0}, C={1,0} and D={-1,0}. Then A and B are harmonic conjugates with respect to C and D. Define the α and β families of circles:

In[43]:=
alphaFamily[t_] := Circle[{(t + 1/t)/2, 0}, RealAbs[t - 1/t]/2];
alphaFamily[1]
Out[44]=
In[45]:=
betaFamily[\[Lambda]_] := Circle[{0, \[Lambda]}, Sqrt[\[Lambda]^2 + 1]]
betaFamily[1]
Out[46]=

Any pair of circles, one from each family, intersects orthogonally:

In[47]:=
pt1 = FullSimplify[
   ResourceFunction[
ResourceObject[<|"Name" -> "CircleIntersection", "ShortName" -> "CircleIntersection", "UUID" -> "7560a8c9-f5e8-4a4d-a75d-6f79737eea04", "ResourceType" -> "Function", "Version" -> "1.0.0", "Description" -> "Find the intersection of two circles", "RepositoryLocation" -> URL[
        "https://www.wolframcloud.com/obj/resourcesystem/api/1.0"], "SymbolName" -> "FunctionRepository`$f4a0b2b9f9ef4a9997eb139de10dc92a`CircleIntersection", "FunctionLocation" -> CloudObject[
        "https://www.wolframcloud.com/obj/9bb5c165-2189-4106-b81a-cf6b395625ff"]|>, ResourceSystemBase -> Automatic]][
    betaFamily[\[Lambda]], alphaFamily[t]],
   Assumptions -> t > 0 && \[Lambda] > 0][[1, 1]]
Out[47]=

Check the dot product of two vectors which sit at each center of the circles and point to the intersection:

In[48]:=
FullSimplify[(pt1 - {0, \[Lambda]}) . (pt1 - {(t + 1/t)/2, 0}), Assumptions -> t > 0 && \[Lambda] > 0]
Out[48]=

This also proves that the locus of the center of circles in the β family (or the perpendicular bisector of segment CD) is the radical axis for any two circles in the α family.

The circles in both coaxial families can be inverted with respect to the reference circle centered at point C:

In[49]:=
style = {{
Hue[
Rational[10, 11]]}, {
Hue[
Rational[9, 11]]}, {
Hue[
Rational[8, 11]]}, {
Hue[
Rational[7, 11]]}, {
Hue[
Rational[6, 11]]}, {
Hue[
Rational[5, 11]]}, {
Hue[
Rational[4, 11]]}, {
Hue[
Rational[3, 11]]}, {
Hue[
Rational[2, 11]]}, {
Hue[
Rational[1, 11]]}, {
Hue[
Rational[1, 11]]}, {
Hue[
Rational[2, 11]]}, {
Hue[
Rational[3, 11]]}, {
Hue[
Rational[4, 11]]}, {
Hue[
Rational[5, 11]]}, {
Hue[
Rational[6, 11]]}, {
Hue[
Rational[7, 11]]}, {
Hue[
Rational[8, 11]]}, {
Hue[
Rational[9, 11]]}, {
Hue[
Rational[10, 11]]}};
\[Lambda]List = {-(5/2), -(9/4), -2, -(7/4), -(3/2), -(5/4), -1, -(
    3/4), -(1/2), -(1/4), 1/4, 1/2, 3/4, 1, 5/4, 3/2, 7/4, 2, 9/4, 5/2};
tList = {-0.8, -0.7333333333333334, -0.6666666666666667, -0.6000000000000001, -0.5333333333333334, -0.46666666666666673`, -0.4, -0.33333333333333337`, -0.2666666666666667, -0.20000000000000007`, 0.2, 0.26666666666666666`, 0.33333333333333337`, 0.4, 0.4666666666666667, 0.5333333333333333, 0.6000000000000001, 0.6666666666666667, 0.7333333333333334, 0.8};
Short[af = alphaFamily /@ tList]
Out[50]=
In[51]:=
Short[bf = betaFamily /@ \[Lambda]List]
Out[51]=
In[52]:=
Short[afInv = ResourceFunction["CircleInversion"][Circle[{1, 0}, 2], #] & /@ af]
Out[52]=
In[53]:=
Short[bfInv = ResourceFunction["CircleInversion"][Circle[{1, 0}, 2], #] & /@ bf]
Out[53]=

The β circles contain the inversion center, and they are thus mapped to lines. The inverses of the α circles are circles, and they must orthogonally intersect the inverses of the β circles. This is due to the anti-conformal property of circle inversion. The only possibility is that the inverse of the α circles are concentric circles with the common center at point C:

In[54]:=
applyStyle[style_, objs_] := MapThread[Append, {style, objs}]
Style[Row[{
     Graphics[{
Text[
Style["\[Alpha]", 14], {4.4, 0}], 
Text[
Style["\[Beta]", 14], {2., 4.9}]}~
       Join~(applyStyle[style, #] & /@ {af, bf})],
     Graphics[{
Text[
Style["\[Alpha]", 14], {14.4, 0}], 
Text[
Style["\[Beta]: lines", 14], {-1, 16.}]}~
       Join~(applyStyle[style, #] & /@ {afInv, bfInv})]}],
   ImageSizeMultipliers -> 0.6] // Framed // Rasterize
Out[55]=

The result implies that one only needs to consider the case of concentric circles to determine the number of circles in a closed Steiner chain. This number is invariant under inversion.

Publisher

Shenghui Yang

Version History

  • 1.0.2 – 15 February 2022
  • 1.0.1 – 19 July 2021

Source Metadata

Related Resources

License Information