Circular inversion

After watching the demonstration of Zvezdelina Stankova on how to prove the Ptolemy’s theorem by using inversion of the plane, I could not resist the urge to implement this projection in a shader and play with.

About the implementation

The implementation of this projection in a shader was much more easy than excepted. The math is trivial: you just have to use sohcahtoa!
In the video of numberphile, mrs Stankova explains that the computation requires to use a tangent to the circle.

Graph showing the projection of B to D

But after one or two failed attempts, using the rule cah returns a solution nearly instantly. The triangle ABC and ACD are isomorphs + rectangles, meaning that they have the same angles and therefore the same edge ratios.
By finding on the cosinus of a with the rule : cos(a) = adjacent / hypothenuse, we can directly find the length of AD by using the same rule.
Once done, we can use a tiny bit of vector math to compute the position of D.
The implentation in the shader looks like this:

// VERTEX ~ B, inversion_center ~ A
vec3 AB = VERTEX-inversion_center;
// length of AB, avoiding division by zero
float hypotenuse = max( 0.00001, length(AB) );

// inversion_radius ~ AC length
float cos_a = inversion_radius / hypotenuse;

// nearly there:
VERTEX = inversion_center + normalize(AB) * cos_a * inversion_radius;

A tiny trick is to use the flag world_vertex_coords : the VERTEX variable will contains the world position of the vertex and not its local position (by default).
In order to display the mesh correctly, you also have to flip the normal and disable the face culling with cull_disabled.
The complete shader is available in the project wiredcity.


You can check a screen recording here:

And here is a gallery of screenshots:

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.