public static void Experiment() { TilingConfig config = new TilingConfig(4, 3); Tiling tiling = new Tiling(); tiling.Generate(config); HashSet <H3.Cell.Edge> completed = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer()); string fileName = "hopf.pov"; using (StreamWriter sw = File.CreateText(fileName)) { Tile[] tiles = tiling.Tiles.ToArray(); //foreach( Tile t in tiling.Tiles ) foreach (Tile t in new Tile[] { tiles[0] }) { foreach (Segment seg in t.Boundary.Segments) { H3.Cell.Edge e = new H3.Cell.Edge(seg.P1, seg.P2); if (completed.Contains(e)) { continue; } HopfLink(sw, Sterographic.PlaneToSphereSafe(e.Start), Sterographic.PlaneToSphereSafe(e.End), anti: false); completed.Add(e); } } } }
private static Vector3D Halfway(Vector3D v1, Vector3D v2) { Vector3D v1_ = Sterographic.PlaneToSphereSafe(v1); Vector3D v2_ = Sterographic.PlaneToSphereSafe(v2); Vector3D result = (v1_ + v2_) / 2; result.Normalize(); return(Sterographic.SphereToPlane(result)); }
public static Vector3D[] CalcViaProjections(Vector3D p1, Vector3D p2, Vector3D p3, int divisions, Geometry g) { if (g == Geometry.Euclidean) { throw new System.NotImplementedException(); } Vector3D h1 = new Vector3D(), h2 = new Vector3D(), h3 = new Vector3D(); if (g == Geometry.Hyperbolic) { h1 = Sterographic.PlaneToHyperboloid(p1); h2 = Sterographic.PlaneToHyperboloid(p2); h3 = Sterographic.PlaneToHyperboloid(p3); } else if (g == Geometry.Spherical) { h1 = Sterographic.PlaneToSphereSafe(p1); h2 = Sterographic.PlaneToSphereSafe(p2); h3 = Sterographic.PlaneToSphereSafe(p3); } List <Vector3D> temp = new List <Vector3D>(); Segment seg1 = Segment.Line(h1, h2); Segment seg2 = Segment.Line(h3, h2); Vector3D[] s1 = seg1.Subdivide(divisions); Vector3D[] s2 = seg2.Subdivide(divisions); for (int i = 0; i < divisions; i++) { Segment seg = Segment.Line(s1[i], s2[i]); temp.AddRange(seg.Subdivide(divisions - i)); } temp.Add(h2); List <Vector3D> result = new List <Vector3D>(); foreach (Vector3D v in temp) { Vector3D copy = v; if (g == Geometry.Hyperbolic) { Sterographic.NormalizeToHyperboloid(ref copy); result.Add(Sterographic.HyperboloidToPlane(copy)); } else if (g == Geometry.Spherical) { copy.Normalize(); result.Add(Sterographic.SphereToPlane(copy)); } } return(result.ToArray()); }
// https://plus.google.com/u/0/117663015413546257905/posts/BnCEkdNiTZ2 public static void TwinDodecs() { Tiling tiling = new Tiling(); TilingConfig config = new TilingConfig(5, 3); tiling.GenerateInternal(config, Polytope.Projection.VertexCentered); // Vertex-centered makes infinities tricky Dodec dodec = new Dodec(); foreach (Tile tile in tiling.Tiles) { foreach (Segment seg in tile.Boundary.Segments) { Vector3D p1 = seg.P1, p2 = seg.P2; if (Infinity.IsInfinite(p1)) { p1 = Infinity.InfinityVector; } if (Infinity.IsInfinite(p2)) { p2 = Infinity.InfinityVector; } dodec.Verts.Add(p1); dodec.Verts.Add(p2); dodec.Midpoints.Add(Halfway(p1, p2)); } } // Now recursively add more vertices. HashSet <Vector3D> allVerts = new HashSet <Vector3D>(); foreach (Vector3D v in dodec.Verts) { allVerts.Add(v); } RecurseTwins(allVerts, dodec, 0); using (StreamWriter sw = File.CreateText("dual_dodecs_points_sphere.pov")) { foreach (Vector3D vert in allVerts) { Vector3D onSphere = Sterographic.PlaneToSphereSafe(vert); sw.WriteLine(PovRay.Sphere(new Sphere() { Center = onSphere, Radius = 0.01 })); //if( !Infinity.IsInfinite( vert ) ) // sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = 0.01 } ) ); } } }
public static Vector3D Centroid(Geometry g, Vector3D[] conformalVerts) { if (g == Geometry.Euclidean) { Vector3D result = new Vector3D(); foreach (Vector3D v in conformalVerts) { result += v; } return(result / conformalVerts.Length); } Vector3D[] verts = conformalVerts.Select(v => { switch (g) { case Geometry.Spherical: return(Sterographic.PlaneToSphereSafe(v)); case Geometry.Hyperbolic: return(Sterographic.PlaneToHyperboloid(v)); } throw new System.ArgumentException(); }).ToArray(); // https://math.stackexchange.com/a/2173370/300001 Vector3D sum = new Vector3D(); for (int i = 0; i < verts.Length; i++) { sum += verts[i]; } Vector3D centroid = sum / Math.Sqrt(DotInGeometry(g, sum, sum)); NormalizeInGeometry(g, ref centroid); switch (g) { case Geometry.Spherical: return(Sterographic.SphereToPlane(centroid)); case Geometry.Hyperbolic: return(Sterographic.HyperboloidToPlane(centroid)); } throw new System.ArgumentException(); }