“Transformations and Projections in Computer Graphics,” 2006, by David  Salomon.

Based on: Circle Inversion Transformation, Section 4.3, page 162.

Some material is from the book,  “Curves and Surfaces for Computer Graphics,” 2006, by David Salomon, and the Mathematica notebook named "Cubic Bezier Curve.nb" found at the website:

MouseOver

Illustrating the Nonlinearity Nature of a Transformation

Circle inversion is an example of a nonlinear transfromation. The inverse of a point P outside the circle is a point Q inside the circle, located on the line that connects P with the origin. Given the four 2 D points in array pts, we compute and plot (in red) the cubic Lagrange polynomial that connects them (Eq. 3.17, page 82 in the book on curves and surfaces). We then invert points pts into qts and compute and plot the same curve (in green) through qts. The two sets of points are also plotted. It is easy to see that the inverse of each point pts that is outside the circle is inside the circle and vice versa, but the green curve  as a whole does not satisfy this property (e.g., the first section of the original, red curve is completely outside the circle, but the first section of the  green curve is not completely inside the circle). This behavior is the result of the nonlinearity of circle inversion.
  We then compute about 50 points of the original curve into rts, and invert each, placing it in array sts. When this array is plotted (with a ListLinePlot, as a blue curve) it is easy to see that in spite of its strange shape it constitutes the true inverse of the original,  red curve.

pts = {{-1.5, 0}, {-0.7, 1}, {0.5, .3}, {1.5, 0}}; (* Four 2D points *)

TensMat = {{-9/2., 27/2, -27/2, 9/2}, {9., -45/2, 18, -9/2}, {-11/2., 9, -9/2, 1}, {1, 0, 0, 0}}; (* Eq. 3.17 *)

g1 = ParametricPlot[{{t^3, t^2, t, 1}.TensMat.pts[[All, 1]], {t^3, t^2, t,  1}.TensMat.pts[[All, 2]]}, {t, 0, 1}, PlotStyle -> Red];
qts = Table[pts[[i]]/(pts[[i, 1]]^2 + pts[[i, 2]]^2), {i, 4}]; (* Inverted points *)

g2 = ParametricPlot[{{t^3, t^2, t, 1}.TensMat.qts[[All, 1]], {t^3, t^2, t, 1}.TensMat.qts[[All, 2]]}, {t, 0, 1}, PlotStyle -> Green];
(* Now generate about 50 points of the original curve *)

rts = Table[{{t^3, t^2, t, 1}.TensMat.pts[[All, 1]], {t^3, t^2, t, 1}.TensMat.pts[[All, 2]]}, {t, 0, 1, 0.02}];
sts = Table[rts[[i]]/(rts[[i, 1]]^2 + rts[[i, 2]]^2), {i, 1, Length[rts]}]; (* Invert them *)
Show[
 Graphics[{Thick, Circle[]}, Axes -> True], g1, Graphics[Point[pts]], 
 Graphics[g2], Graphics[{PointSize[Medium], Point[qts]}], 
 ListLinePlot[sts, PlotStyle -> Blue]]

(Below are a couple of embelished examples, but without user interaction capability.)

Example 1:

backGroundColor=Polygon[{ImageScaled[{0,0}],ImageScaled[{1,0}],ImageScaled[{1,1}],ImageScaled[{0,1}]},VertexColors->{LightBlue,LightGreen,LightYellow,LightRed}];
pts={{-1.5,0},{-0.7,1},{0,.3},{1.5,0}}; (*<-Four 2D points on red curve. *)
TensMat={{-9/2.,27/2,-27/2,9/2},{9.,-45/2,18,-9/2},{-11/2.,9,-9/2,1},{1,0,0,0}}; (* Eq. 3.17, C & S book. *)
g1= ParametricPlot[{{t^3,t^2,t,1}.TensMat.pts[[All,1]],{t^3,t^2,t,1}.TensMat.pts[[All,2]]},{t,0,1}, PlotStyle->{DotDashed,Red,Thickness[0.007]},Axes->True,AxesLabel->{"+X","+Y"}];
qts=Table[pts[[i]]/(pts[[i,1]]^2+pts[[i,2]]^2), {i,4}]; (* Inverted points *)
g2= ParametricPlot[{{t^3,t^2,t,1}.TensMat.qts[[All,1]],{t^3,t^2,t,1}.TensMat.qts[[All,2]]},{t,0,1}, PlotStyle->{Dotted,Darker[Green],Thickness[0.01]}];
(* Now generate about 50 points of the original curve *)
rts = Table[{{t^3,t^2,t,1}.TensMat.pts[[All,1]],{t^3,t^2,t,1}.TensMat.pts[[All,2]]},{t,0,1,0.02}];
sts=Table[rts[[i]]/(rts[[i,1]]^2+rts[[i,2]]^2), {i,1,Length[rts]}]; (* Invert them *)
Show[Graphics[{Directive[Antialiasing->True,Thick],Circle[]}],g1,Graphics[{Magenta,PointSize[0.017],Point[pts]}],Graphics[g2],Graphics[{Cyan,PointSize[0.02],Point[qts]}],ListLinePlot[sts, PlotStyle->{Dashing[.02],Blue,Thickness[.006]}],Prolog->backGroundColor,PlotRangeClipping->False,ImageSize->600,Frame->True,FrameLabel->"Example 1:",LabelStyle->Directive[Purple,Bold,14],Axes->True,AxesLabel->{"+x","+y"},AxesStyle->Directive[Dashed,16]];
Labeled[%,Text[Style["~CIRCLE INVERSION~",24,Bold,FontFamily->"Rockwell Extra Bold",Darker[Cyan]]],Top];
Framed[%,Background->Lighter[Lighter[LightCyan]]]
Framed[Dynamic[MousePosition["Graphics"]],Background->LightOrange]

Example 2:

backGroundColor=Polygon[{ImageScaled[{0,0}],ImageScaled[{1,0}],ImageScaled[{1,1}],ImageScaled[{0,1}]},VertexColors->{LightBlue,LightGreen,LightYellow,LightRed}];
pts={{-1.5,0},{-0.7,1},{0.7,.5},{0.5,-0.2}}; (*<-Four 2D points on red curve. *)
TensMat={{-9/2.,27/2,-27/2,9/2},{9.,-45/2,18,-9/2},{-11/2.,9,-9/2,1},{1,0,0,0}}; (* Eq. 3.17, C & S book. *)
g1= ParametricPlot[{{t^3,t^2,t,1}.TensMat.pts[[All,1]],{t^3,t^2,t,1}.TensMat.pts[[All,2]]},{t,0,1}, PlotStyle->{DotDashed,Red,Thickness[0.007]},Axes->True,AxesLabel->{"+X","+Y"}];
qts=Table[pts[[i]]/(pts[[i,1]]^2+pts[[i,2]]^2), {i,4}]; (* Inverted points *)
g2= ParametricPlot[{{t^3,t^2,t,1}.TensMat.qts[[All,1]],{t^3,t^2,t,1}.TensMat.qts[[All,2]]},{t,0,1}, PlotStyle->{Dotted,Darker[Darker[Green]],Thickness[0.01]}];
(* Now generate about 50 points of the original curve *)
rts = Table[{{t^3,t^2,t,1}.TensMat.pts[[All,1]],{t^3,t^2,t,1}.TensMat.pts[[All,2]]},{t,0,1,0.02}];
sts=Table[rts[[i]]/(rts[[i,1]]^2+rts[[i,2]]^2), {i,1,Length[rts]}]; (* Invert them *)
lm1=Graphics[Locator[{-1.5,0},Appearance->Medium,Background->Magenta]];
lm2=Graphics[Locator[{1.5,0},Appearance->Medium,Background->Magenta]];
lc1=Graphics[Locator[{-0.6666666666666666`,0},Appearance->Large,Background->Cyan]];
lc2=Graphics[Locator[{0.6666666666666666`,0},Appearance->Large,Background->Cyan]];
Show[Graphics[{Directive[Antialiasing->True,Thick],Circle[]}],lm1,lm2,lc1,lc2,g1,Graphics[{Magenta,PointSize[0.017],Point[pts]}],Graphics[g2],Graphics[{Cyan,PointSize[0.02],Point[qts]}],ListLinePlot[sts, PlotStyle->{Dashing[.02],Blue,Thickness[.006]}],Prolog->backGroundColor,PlotRangeClipping->False,ImageSize->600,Frame->True,FrameLabel->"Example 2:",LabelStyle->Directive[Purple,Bold,14],Axes->True,AxesLabel->{"+x","+y"},AxesStyle->Directive[Dashed,16]];
Labeled[%,Text[Style["~CIRCLE INVERSION~",24,Bold,FontFamily->"Jokewood",Darker[Cyan]]],Top];
Framed[%,Background->Lighter[Lighter[LightCyan]]]
Framed[Dynamic[MousePosition["Graphics"]],Background->LightOrange]

Exercise: Develop user interactive code using Mathematica built-in functions like Manipulate and Dynamic, for plotting and interacting with the Circle Inversion plots.


Mathematica 6.0.1.  11-08-2008.