private void CalculateFromTwoPolygonsInternal(Polygon home, Polygon boundary, CircleNE homeVertexCircle, Geometry g) { // ZZZ - We have to use the boundary, but that can be projected to infinity for some of the spherical tilings. // Trying to use the Drawn tile produced weird (yet interesting) results. Polygon poly1 = boundary; Polygon poly2 = home; if (poly1.Segments.Count < 3 || poly2.Segments.Count < 3) // Poor poor digons. { Debug.Assert(false); return; } // Same? Vector3D p1 = poly1.Segments[0].P1, p2 = poly1.Segments[1].P1, p3 = poly1.Segments[2].P1; Vector3D w1 = poly2.Segments[0].P1, w2 = poly2.Segments[1].P1, w3 = poly2.Segments[2].P1; if (p1 == w1 && p2 == w2 && p3 == w3) { this.Mobius = Mobius.Identity(); return; } Mobius m = new Mobius(); m.MapPoints(p1, p2, p3, w1, w2, w3); this.Mobius = m; // Worry about reflections as well. if (g == Geometry.Spherical) { // If inverted matches the orientation, we need a reflection. bool inverted = poly1.IsInverted; if (!(inverted ^ poly1.Orientation)) { this.Reflection = homeVertexCircle; } } else { if (!poly1.Orientation) { this.Reflection = homeVertexCircle; } } // Some testing. Vector3D test = this.Apply(boundary.Center); if (test != home.Center) { // ZZZ: What is happening here is that the mobius can project a point to infinity before the reflection brings it back to the origin. // It hasn't been much of a problem in practice yet, but will probably need fixing at some point. //Trace.WriteLine( "oh no!" ); } }