<<Hyperbolic.m

Conversions between the various models

Convert[PoincareBall[{.3,.4}],Projective]

Convert[%,PoincareBall]

Convert[PoincareBall[{.3,.4}],Minkowski]

Convert[Minkowski[{1,2,3}],PoincareBall]

This is garbage, because {1,2,3} was not normalized.
Minkowski points generated by Convert are automatically normalized unless they're at infinity. We need instead the following invocation:

Convert[Normalize[Minkowski[{1,2,3}]],PoincareBall]

Convert[%,Minkowski]

We can also map tangent vectors between the various models.

v1=PoincareBall[Vector[{0,0},{0,1}]]

v2=Convert[v1,Projective]

VectorLength /@ {v1,v2}

Finding the (2,3,7) triangle

We'll solve the (2,3,7) triangle.  Let the Pi/3 angle be at the origin, and the short edge along the x-axis.  In the projective mode, the right angle will be at {a,0} and the Pi/7
angle will be at {a,a Sqrt[3]}.

p={a,a Sqrt[3]}

Angle[Projective[Vector[p,{0,-1}]],Projective[Vector[p,-p]]] //
  Short

Cos[%] // Simplify

sols = Solve[N[%==Cos[Pi/7]],a]

p1 = Projective[N[p /. %[[1]]]]

p2= Projective[{%[[1,1]],0}]

p3=Projective[{0,0}]

SetOptions[Convert, Model -> PoincareBall];

Show[Graphics[{
      UnitCircle,
      Line[{p1,p2,p3,p1}]
      },
   AspectRatio -> Automatic]]

Distance[p1,p2]

{q1,q2,q3} = Convert[#,PoincareBall]& /@ {p1,p2,p3}

Distance[q1,q2]

We'll build up the reflection in each of the three sides. The reflection in side p2-p3 takes a positive frame including Vector[{0,0},{1,0}] to a negative frame including the same vector.

CompleteFrame[PoincareBall[Vector[{0,0},{1,0}]]]

CompleteFrame[PoincareBall[Vector[{0,0},{1,0}]],-1]

r23=Isometry[%%,%]

%.PoincareBall[{.3,.4}]

CompleteFrame[PoincareBall[Vector[Peel[q2],{0,1}]]]

Peel[q2] peels off the label, PoincareBall.  First would also work.

CompleteFrame[PoincareBall[Vector[Peel[q2],{0,1}]],-1]

r12=Isometry[%%,%] //Chop

Now find the inverse transformation. We expect the same, since this is a reflection.

Inverse[%]

%.PoincareBall[{0,0}]

{Distance[q2,q3],Distance[q2,%]}

Reflection preserves distances.

CompleteFrame[PoincareBall[Vector[Peel[q1],-Peel[q1]]]]

CompleteFrame[PoincareBall[Vector[Peel[q1],-Peel[q1]]],-1]

r13=Isometry[%%,%] // Chop

r13.r23.r13.r23.r13.r23 // Chop

r23.r12.r23.r12 // Chop

r12.r13.r12.r13.r12.r13.r12.r13.r12.r13.r12.r13.r12.r13 // Chop

Points near the circle at infinity

Find where the geodesic determined by this vector intersects the sphere by walking 100 units along it, we get pretty close to the boundary; in the future there may be a special function to do this right.

Drag[PoincareBall[Vector[Peel[q2],{0,1}]],100] //N

Distance[q2,First /@ %]

This should be 100, but because of roundoff the point defined above is actually slightly outside the ball, with unpredictable consequences