public static Mobius VertexCenteredMobius(int p, int q) { double angle = Math.PI / q; if (Utils.Even(q)) { angle *= 2; } Vector3D offset = new Vector3D(-1 * Geometry2D.GetNormalizedCircumRadius(p, q), 0, 0); offset.RotateXY(angle); Mobius m = new Mobius(); m.Isometry(Geometry2D.GetGeometry(p, q), angle, offset.ToComplex()); return(m); }
public void CreateRegular(int numSides, int q) { int p = numSides; Segments.Clear(); List <Vector3D> points = new List <Vector3D>(); Geometry g = Geometry2D.GetGeometry(p, q); double circumRadius = Geometry2D.GetNormalizedCircumRadius(p, q); double angle = 0; for (int i = 0; i < p; i++) { Vector3D point = new Vector3D(); point.X = (circumRadius * Math.Cos(angle)); point.Y = (circumRadius * Math.Sin(angle)); points.Add(point); angle += Utils.DegreesToRadians(360.0 / p); } // Turn this into segments. for (int i = 0; i < points.Count; i++) { int idx1 = i; int idx2 = i == points.Count - 1 ? 0 : i + 1; Segment newSegment = new Segment(); newSegment.P1 = points[idx1]; newSegment.P2 = points[idx2]; if (g != Geometry.Euclidean) { newSegment.Type = SegmentType.Arc; if (2 == p) { // Our magic formula below breaks down for digons. double factor = Math.Tan(Math.PI / 6); newSegment.Center = newSegment.P1.X > 0 ? new Vector3D(0, -circumRadius, 0) * factor : new Vector3D(0, circumRadius, 0) * factor; } else { // Our segments are arcs in Non-Euclidean geometries. // Magically, the same formula turned out to work for both. // (Maybe this is because the Poincare Disc model of the // hyperbolic plane is stereographic projection as well). double piq = q == -1 ? 0 : Math.PI / q; // Handle q infinite. double t1 = Math.PI / p; double t2 = Math.PI / 2 - piq - t1; double factor = (Math.Tan(t1) / Math.Tan(t2) + 1) / 2; newSegment.Center = (newSegment.P1 + newSegment.P2) * factor; } newSegment.Clockwise = Geometry.Spherical == g ? false : true; } // XXX - Make this configurable? // This is the color of cell boundary lines. //newSegment.m_color = CColor( 1, 1, 0, 1 ); Segments.Add(newSegment); } }