public static void CalcEScale() { // Euclidean scale is arbitrary, but put it in the middle of the projections of 433 and 435. double r3 = Spherical2D.s2eNorm(Honeycomb.CircumRadius(4, 3, 3)); double r5 = DonHatch.h2eNorm(Honeycomb.CircumRadius(4, 3, 5)); m_eScale = (r3 + r5) / (2 * Math.Sqrt(3)); }
public static Vector3D EdgeMidpointSpherical(int p, int q, int r) { // Get a {q,p} tiling on the z=0 plane. Segment[] baseTileSegments = BaseTileSegments(q, p); Vector3D direction = H3Models.UHSToBall(baseTileSegments.First().Midpoint); direction.Normalize(); double midRadius = Spherical2D.s2eNorm(Honeycomb.MidRadius(p, q, r)); return(direction * midRadius); }
public static Vector3D FaceCenterSpherical(int p, int q, int r) { // Get a {q,p} tiling on the z=0 plane. Segment[] baseTileSegments = BaseTileSegments(q, p); // This will be unit length. Vector3D pFaceDirection = H3Models.UHSToBall(baseTileSegments.First().P1); // In-radius is in conformal model double inRadius = Spherical2D.s2eNorm(Honeycomb.InRadius(p, q, r)); return(pFaceDirection * inRadius); }
/// <summary> /// Mirrors for Spherical geometry, in the ball model. /// </summary> public static Sphere[] MirrorsSpherical(int p, int q, int r) { // Get a {q,p} tiling on the z=0 plane. Segment[] baseTileSegments = BaseTileSegments(q, p); // This will be unit length. Vector3D pFaceDirection = H3Models.UHSToBall(baseTileSegments.First().P1); // In-radius is in conformal model double inRadius = Spherical2D.s2eNorm(Honeycomb.InRadius(p, q, r)); double centerOfSphereNE = (1 - inRadius) / (1 + inRadius); Vector3D center; double radius; H3Models.Ball.DupinCyclideSphere(-pFaceDirection * centerOfSphereNE, 1.0 /*geodesic circle*/, Geometry.Spherical, out center, out radius); Sphere cellBoundary = new Sphere() { Center = center, Radius = radius, Invert = true }; Sphere[] interior = InteriorMirrors(p, q); interior = interior.Select(s => H3Models.UHSToBall(s)).ToArray(); Sphere[] surfaces = new Sphere[] { cellBoundary, interior[0], interior[1], interior[2] }; // Apply rotations. bool applyRotations = false; if (applyRotations) { double rotation = Math.PI / 2; foreach (Sphere s in surfaces) { RotateSphere(s, rotation); } } return(surfaces); }
/// <summary> /// Our approach will be: /// (1) Generate a portion of one cell. /// (2) Reflect all facets in the central facet, to get things filled-in inside the central facet. (Trim small edges here?) /// (3) Copy this region around the plane, and go back to step (2) if density is not high enough. /// (4) Map to Ball, trimming edges that become too small. /// NOTE: All verts are on the boundary, so we can reflect around // in circles on the plane at infinity, rather than spheres. /// </summary> public static void GenerateExotic(EHoneycomb honeycomb, H3.Settings settings) { settings.AngularThickness = 0.17; Tiling tiling; Tile baseTile; GetAssociatedTiling(honeycomb, out tiling, out baseTile); List <H3.Cell.Edge> edges = new List <H3.Cell.Edge>(); foreach (Segment seg in baseTile.Boundary.Segments) { edges.Add(new H3.Cell.Edge(seg.P1, seg.P2)); } settings.Position = Polytope.Projection.FaceCentered; double scale = 1; Vector3D offset = new Vector3D(); if (settings.Position == Polytope.Projection.FaceCentered) { scale = FaceCenteredScale(baseTile.VertexCircle); offset = new Vector3D(); } else if (settings.Position == Polytope.Projection.EdgeCentered) { scale = EdgeCenteredScale(baseTile); offset = baseTile.Boundary.Segments[0].Midpoint; } int iterations = m_params.Iterations; for (int i = 0; i < iterations; i++) { edges = DoOneStep(edges, tiling, baseTile.VertexCircle); } edges = CopyAndProject(edges, tiling, scale, offset); if (m_params.RemoveDangling) { Dictionary <H3.Cell.Edge, int> edgeDict = edges.ToDictionary(e => e, e => 1); H3.RemoveDanglingEdgesRecursive(edgeDict); edges = edgeDict.Keys.ToList(); } string outputFileName = H3.m_baseDir + Honeycomb.String(honeycomb, false); System.IO.File.Delete(outputFileName); if (m_params.Output == H3.Output.STL) { outputFileName += ".stl"; // Now mesh the edges. Shapeways mesh = new Shapeways(); foreach (H3.Cell.Edge edge in edges) { // Append to the file vs. writing out all at once because I was running out of memory otherwise. mesh = new Shapeways(); int div; H3Models.Ball.LODThin(edge.Start, edge.End, out div); mesh.Div = div; H3.Util.AddToMeshInternal(mesh, edge.Start, edge.End); mesh.Mesh.Scale(settings.Scale); STL.AppendMeshToSTL(mesh.Mesh, outputFileName); } } else { outputFileName += ".pov"; PovRay.WriteH3Edges(new PovRay.Parameters() { AngularThickness = settings.AngularThickness, Halfspace = settings.Halfspace, ThinEdges = settings.ThinEdges, }, edges.ToArray(), outputFileName); } }
private static void GetPQ(EHoneycomb honeycomb, out int p, out int q) { int r; Honeycomb.PQR(honeycomb, out p, out q, out r); }
public static Vector3D VertexSpherical(int p, int q, int r) { double circumRadius = Spherical2D.s2eNorm(Honeycomb.CircumRadius(p, q, r)); return(new Vector3D(0, 0, -circumRadius)); }
public static void Generate(EHoneycomb honeycomb, H3.Settings settings) { // XXX - Block the same as in H3. Share code better. H3.Cell template = null; { int p, q, r; Honeycomb.PQR(honeycomb, out p, out q, out r); // Get data we need to generate the honeycomb. Polytope.Projection projection = Polytope.Projection.FaceCentered; double phi, chi, psi; H3.HoneycombData(honeycomb, out phi, out chi, out psi); H3.SetupCentering(honeycomb, settings, phi, chi, psi, ref projection); Tiling tiling = new Tiling(); TilingConfig config = new TilingConfig(p, q); tiling.GenerateInternal(config, projection); H3.Cell first = new H3.Cell(p, H3.GenFacets(tiling)); first.ToSphere(); // Work in ball model. first.ScaleToCircumSphere(1.0); first.ApplyMobius(settings.Mobius); template = first; } // Center Vector3D center = template.Center; // Face H3.Cell.Facet facet = template.Facets[0]; Sphere s = H3Models.Ball.OrthogonalSphereInterior(facet.Verts[0], facet.Verts[1], facet.Verts[2]); Vector3D face = s.Center; face.Normalize(); face *= DistOriginToOrthogonalSphere(s.Radius); // Edge Circle3D c; H3Models.Ball.OrthogonalCircleInterior(facet.Verts[0], facet.Verts[1], out c); Vector3D edge = c.Center; edge.Normalize(); edge *= DistOriginToOrthogonalSphere(c.Radius); // Vertex Vector3D vertex = facet.Verts[0]; Tet fundamental = new Tet(center, face, edge, vertex); // Recurse. int level = 1; Dictionary <Tet, int> completedTets = new Dictionary <Tet, int>(new TetEqualityComparer()); completedTets.Add(fundamental, level); List <Tet> tets = new List <Tet>(); tets.Add(fundamental); ReflectRecursive(level, tets, completedTets, settings); Shapeways mesh = new Shapeways(); foreach (KeyValuePair <Tet, int> kvp in completedTets) { if (Utils.Odd(kvp.Value)) { continue; } Tet tet = kvp.Key; // XXX - really want sphere surfaces here. mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[1], tet.Verts[2])); mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[3], tet.Verts[1])); mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[2], tet.Verts[3])); mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[1], tet.Verts[3], tet.Verts[2])); } mesh.Mesh.Scale(settings.Scale); STL.SaveMeshToSTL(mesh.Mesh, H3.m_baseDir + "fundamental" + ".stl"); }
public static double PiOverNSafe(int n) { return(Honeycomb.PiOverNSafe(n)); }
public static Geometry GetGeometry(int p, int q, int r) { return(Honeycomb.GetGeometry(p, q, r)); }