# Geometric Inversion, WolframLang Code

By Xah Lee. Date: . Last updated: .

### geometric inversion of a 2d grid

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);
cArray = CoordinateBoundsArray[{{-1, 1}, {-1, 1}}, Into ];
hLines= (BlockMap[Line,#,2,1]&) /@ cArray;
vLines= (BlockMap[Line,#,2,1]&) /@ Transpose @ cArray;
gp1 = {hLines , vLines};
gp2 = gp1 /. Line[x_] :> Line[ geoInv /@ x ];
GraphicsGrid[{{Graphics[gp1, Axes->True ], Graphics[gp2, Axes->True ]}} ]```

note that we apply the geometric inversion function on the grid points only, not on the lines themselfs. This results more artistic images. Normally, inversion of lines becomes circles, so you don't have the spider web kinda image.

[see Geometric Inversion]

Also, note the syntax highlighting there. That's xah-wolfram-mode in emacs. [see Emacs: Xah Wolfram Mode]

### geometric inversion of squares on grid

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);

xRange=1;
gridDivN = 15;
δ=xRange 2/gridDivN;
sqWidth=δ * 8/10;
s=sqWidth/2;

squaresGP=
Table[
With[{ a={x-s,y-s},b={x+s,y-s},c={x+s,y+s},d={x-s,y+s}},
GraphicsComplex[{a,b,c,d},Line@{1,2,3,4,1}]
]
,{x,-xRange,xRange,δ},{y,-xRange,xRange,δ}];

gp2= squaresGP /. GraphicsComplex[x_, r__] :> GraphicsComplex[geoInv /@ x, r];

GraphicsGrid[{{Graphics[squaresGP, Axes->True ], Graphics[gp2, Axes->True, PlotRange->9 ]}} ]```

### geometric inversion of regular polygons on square grid

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);

gridWidth = 2;
gridDivN = 13;
step = gridWidth/gridDivN;
polygonNumOfSides = 8;
polygonRadius =step /2 2.2 ;
polygonRotation = 2 Pi/8;

polygonVertexes = ((({Cos[#], Sin[#]} polygonRadius) &) /@ Range[polygonRotation, 2 π+polygonRotation - 2 π/polygonNumOfSides/2, 2 π/polygonNumOfSides ]);

gp1 =
Map[ Function[{x}, GraphicsComplex[ ((x+#) &) /@ polygonVertexes, Line @ Append[Range @polygonNumOfSides, 1] ]],
CoordinateBoundsArray[{{-gridWidth/2, gridWidth/2}, {-gridWidth/2, gridWidth/2}}, step]
, {2}];

gp2= gp1 /. GraphicsComplex[x_, r__] :> GraphicsComplex[geoInv /@ x, r];

gr1 = Graphics[gp1, Axes->True ]
gr2 = Graphics[gp2, Axes->True, PlotRange->4 ]

GraphicsGrid[ {{gr1, gr2}} ]```
• Use `{Cos[t] , Sin[t]} rr` to generate vertexes of polygon.
• Use `CoordinateBoundsArray` to generate grid of points.

### geometric inversion as decorative pavement tiles

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);

xRange=1;
gridDivN = 15;
δ=xRange 2/gridDivN;
sqWidth=δ * 8/10;
s=sqWidth/2;
tileHeight= -2;

squaresGP=
Table[
With[{ a={x-s,y-s},b={x+s,y-s},c={x+s,y+s},d={x-s,y+s}},
GraphicsComplex[{a,b,c,d},Line@{1,2,3,4,1}]
]
,{x,-xRange,xRange,δ},{y,-xRange,xRange,δ}];

Graphics[squaresGP, Axes -> True ]

gp2= squaresGP /. GraphicsComplex[x_, r__] :> GraphicsComplex[geoInv /@ x, r];

gp3d= gp2 /. GraphicsComplex[x_, r__] :> GraphicsComplex[ ( Append[#,0] &) /@ x, r];

Graphics3D[gp3d, Axes -> True, PlotRange-> {{-4,4},{-4,4},{-1,1}} ]

tilesGP = gp3d /. GraphicsComplex[pts_, Line[x_]]  :>
GraphicsComplex[ Join[pts,((#+{0, 0, tileHeight}) &) /@ pts],
List@Polygon@{Drop[x,-1], {1, 5, 6, 2}, {2, 6, 7, 3}, {3, 7, 8, 4}, {4, 8, 5, 1}, {5, 6, 7, 8}}
];

Graphics3D[tilesGP, Axes -> True, PlotRange-> {{-4,4},{-4,4},{-1,1}} ]```

### prevent congestion in center

because geometric inversion will swap points outside a circe to inside, so, it became very dense near the center of the circle. We want to prevent that, so garden pavement tiles don't become infinitely small.

we do this by applying the geometric inversion to grid points, also, square is also resized by the inversion. Then, we apply geometric inversion to them.

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);

gridDivN = 16;
nGon = 4;
rr = (2/gridDivN) /2 (Sqrt@2) .7;
α = 2 Pi/8;

gridPoints = Map[ geoInv , CoordinateBoundsArray[{{-1,1},{-1,1}}, Into@gridDivN], {2}] ;

gp1=
With[{sq= ((({Cos[#] , Sin[#]} rr) &) /@ Range[α, 2 π+α - 2 π/nGon/2, 2 π/nGon ]) },
Map[ Function[{x}, GraphicsComplex[ ((x+#) &) /@ (sq x.x), Line @ Append[Range @nGon,1] ]],
gridPoints
,{2}]
];

gp2= gp1 /. GraphicsComplex[x_, r__] :> GraphicsComplex[geoInv /@ x, r];

gr1 = Graphics[gp1, Axes->True ]
gr2 = Graphics[gp2, Axes->True ]

GraphicsGrid[ {{gr1, gr2}} ]```

### 3d tile

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);

gridWidth = 2;
gridDivN = 14;
polygonRadius = gridWidth/gridDivN/2 .7;
polygonNumSides = 4;
polygonRotate = 2 Pi/8;
tileHeight = -0.2;

gridPoints = Map[ geoInv , CoordinateBoundsArray[{{-gridWidth/2, gridWidth/2}, {-gridWidth/2, gridWidth/2}}, Into@gridDivN], {2}] ;

polygonVertexes = ((({Cos[#], Sin[#]} polygonRadius Sqrt@2)&) /@ Range[polygonRotate, 2 π+polygonRotate - 2 π/polygonNumSides/2, 2 π/polygonNumSides]);

gPolygons2D = Map[
Function[{pt},
GraphicsComplex[ ((pt+#) &) /@ (polygonVertexes (pt.pt)), Line @ Append[Range@polygonNumSides, 1] ]],
gridPoints, {2}];

Graphics[gPolygons2D, Axes -> True ]

g2GeoInvert = gPolygons2D /. GraphicsComplex[pts_, r__] :> GraphicsComplex[geoInv /@ pts, r];

Graphics[g2GeoInvert, Axes -> True ]

g3D = g2GeoInvert /. GraphicsComplex[x_, r__]:>GraphicsComplex[( Append[#, 0]&) /@ x, r];

Graphics3D[g3D, Axes -> True]

g4Tiles3D = g3D /. GraphicsComplex[pts_, Line[indexes_]]  :>
GraphicsComplex[
Join[pts, ((#+{0, 0, tileHeight}) &) /@ pts],
Polygon@
With[{
polyTop = Range[polygonNumSides],
rangeX = Partition[ Append[Range[polygonNumSides], 1], 2, 1],
polyBottom = Range[polygonNumSides+1, 2 polygonNumSides]
},
Join[
{polyTop},
((With[{x = First@#, y = Last@#}, {x, y, y+polygonNumSides, x+polygonNumSides}] &) /@ rangeX ),
{polyBottom}
]
]
];

Graphics3D[g4Tiles3D, Axes -> True]```

### geometric inversion of cubes on 3d grid

```geoInv = ((With[{x = #.#}, If[ x < 0.00000001, #, #/x] ]) &);
cubes = Table[Cube[{x, y, z}, 0.8], {x, -3, 3}, {y, 0, 3}, {z, -3, 3}] /. Cube[{(0)..}, _] -> Nothing;
Graphics3D[{Cyan, cubes /. x_Cube -> CanonicalizePolyhedron[x] /. Polyhedron[pts_, g_] :> Polyhedron[geoInv /@ pts, g]}, Boxed -> False, PlotRange -> 0.4]```

## ideas for pretty graphics with geometric inversion

2021-08-02 do geometric inversion, of a rectangular grid, or 3d grid. 2d case, and 3d case. For 2d case, there are 2 renderings.

• Use line segments.
• Use square patches.

For each case, there are 2 variations.

• transform on line end points, or cube square vertexes.
• break line small line segments or break square patch into into tiny squares, then transform the vertexes. This results fine curves.
• Consider writing a function that transform line into circle arc. That is, given 2 points, return something like arc2d[center,radius, sweepAngle , startAngle]

Now, to make them pretty:

• use tube instead of line.
• add a bit height to square, so they become 3d tiles.

### 3d case

Now, geometric inversion of 3d grid. We can use tubes, or cubes. Similar consideration with 2d case.