Example #1
0
        /// <summary>
        /// Outputs edges to an stl file.
        /// </summary>
        public void Output()
        {
            System.Func <Vector3D, Vector3D> p2s       = v => Spherical2D.PlaneToSphere(v);
            System.Func <Vector3D, Vector3D> transform = v => H3Models.Ball.ApplyMobius(Mobius.Scale(3), v);

            double min  = double.MaxValue;
            Cell   cell = m_cells.First();

            foreach (Vector3D v1 in cell.Tiles[0].Boundary.Vertices)
            {
                foreach (Vector3D v2 in cell.Tiles[1].Boundary.Vertices)
                {
                    min = Math.Min(min, p2s(v1).Dist(p2s(v2)));
                }
            }

            // XXX - code below so ugly to read!

            Dictionary <TileVertex, TileVertex> vMap = new Dictionary <TileVertex, TileVertex>();

            for (int tile_i = 0; tile_i < cell.Tiles.Length; tile_i++)
            {
                for (int tile_j = tile_i + 1; tile_j < cell.Tiles.Length; tile_j++)
                {
                    for (int vertex_i = 0; vertex_i < cell.Tiles[tile_i].Boundary.Vertices.Length; vertex_i++)
                    {
                        for (int vertex_j = 0; vertex_j < cell.Tiles[tile_j].Boundary.Vertices.Length; vertex_j++)
                        {
                            Vector3D v1 = cell.Tiles[tile_i].Boundary.Vertices[vertex_i];
                            Vector3D v2 = cell.Tiles[tile_j].Boundary.Vertices[vertex_j];

                            if (Tolerance.Equal(p2s(v1).Dist(p2s(v2)), min))
                            {
                                vMap[new TileVertex(tile_i, vertex_i)] = new TileVertex(tile_j, vertex_j);
                            }
                        }
                    }
                }
            }

            HashSet <H3.Cell.Edge> edges = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer());

            foreach (Cell c in m_cells)
            {
                foreach (KeyValuePair <TileVertex, TileVertex> kvp in vMap)
                {
                    Vector3D v1 = transform(p2s(c.Tiles[kvp.Key.Item1].Boundary.Vertices[kvp.Key.Item2]));
                    Vector3D v2 = transform(p2s(c.Tiles[kvp.Value.Item1].Boundary.Vertices[kvp.Value.Item2]));
                    edges.Add(new H3.Cell.Edge(v1, v2));
                }
            }

            //H3.m_settings.ThinEdges = true;
            H3.SaveToFile("ultrainf", edges.ToArray(), finite: false);
        }
Example #2
0
        public static H3.Cell.Edge[] OneHoneycombOrthoscheme(HoneycombDef def, int[] active, int baseHue, Settings settings = null)
        {
            // Setup parameters.
            int numEdges = 250000;

            if (settings != null)
            {
                active   = settings.PovRay.Active;
                def      = new HoneycombDef(settings.P, settings.Q, settings.R);
                numEdges = settings.PovRay.NumEdges;
            }

            CalcThickness(active);
            if (settings != null)
            {
                H3.m_settings.AngularThickness = settings.PovRay.EdgeWidth;                     // ZZZ - should really stop using that settings class.
            }
            string baseName      = BaseName(def);
            string mirrorsString = ActiveMirrorsString(active);
            string suffix        = "-" + mirrorsString;
            string fileName      = baseName + suffix;

            if (ViewPath != null)
            {
                fileName += string.Format("_{0:D4}", ViewPath.Step);
            }

            if (File.Exists(fileName + ".pov"))
            {
                File.Delete(fileName + ".pov");
                //Console.WriteLine( string.Format( "Skipping {0}", fileName ) );
                //return;
            }

            Program.Log(string.Format("Building {0}", fileName));

            // The wiki mirrors are labeled in the reverse of ours.
            Func <int, int> mapMirror = i => 3 - i;

            active = active.Select(i => mapMirror(i)).OrderBy(i => i).ToArray();

            Simplex simplex = new Simplex();

            simplex.Facets = SimplexCalcs.Mirrors(def.P, def.Q, def.R);
            simplex.Verts  = SimplexCalcs.VertsBall(def.P, def.Q, def.R);

            Vector3D startingPoint = IterateToStartingPoint(def, active, simplex);

            if (startingPoint.DNE)
            {
                return(null);
            }
            List <H3.Cell.Edge> startingEdges = new List <H3.Cell.Edge>();

            foreach (int a in active)
            {
                Vector3D reflected = simplex.ReflectInFacet(startingPoint, a);
                startingEdges.Add(new H3.Cell.Edge(startingPoint, reflected));
                //startingEdges.Add( new H3.Cell.Edge( simplex.Verts[0], simplex.Verts[3] ) );	// Used for Borromean Rings complement image.
            }

            if (false)
            {
                Vector3D[] kv = simplex.Verts.Select(v => HyperbolicModels.PoincareToKlein(v)).ToArray();
                kv[3] = SimplexCalcs.VertexPointKlein(def.P, def.Q, def.R);
                Vector3D t       = (kv[3] - kv[0]) * 0.5;
                Sphere   gSphere = H3Models.Ball.OrthogonalSphereInterior(HyperbolicModels.KleinToPoincare(t));
                gSphere = H3Models.BallToKlein(gSphere);
                Vector3D t2 = Euclidean3D.IntersectionPlaneLine(gSphere.Normal, gSphere.Offset, kv[3] - kv[2], kv[2]);
                //t2 = kv[2] + ( kv[3] - kv[2]) * 0.5;

                t  = HyperbolicModels.KleinToPoincare(t);
                t2 = HyperbolicModels.KleinToPoincare(t2);
                startingEdges.Add(new H3.Cell.Edge(t, t2));
                startingEdges.Add(new H3.Cell.Edge(t, simplex.ReflectInFacet(t, 3)));
            }

            // If we are doing a view path, transform our geometry.
            if (ViewPath != null)
            {
                //Vector3D p = new Vector3D( 0, 0, .5 );
                Vector3D p = new Vector3D(0.08, 0.12, 0.07);
                simplex.Facets = simplex.Facets.Select(f => H3Models.Transform_PointToOrigin(f, p)).ToArray();
                simplex.Verts  = simplex.Verts.Select(v => H3Models.Transform_PointToOrigin(v, p)).ToArray();
                startingEdges  = startingEdges.Select(e => new H3.Cell.Edge(
                                                          H3Models.Transform_PointToOrigin(e.Start, p),
                                                          H3Models.Transform_PointToOrigin(e.End, p))).ToList();
            }

            SetupBaseHue(fileName, mirrorsString, baseHue);
            Recurse.m_background = baseHue == -1 ? new Vector3D() : new Vector3D(baseHue, 1, .1);

            H3.Cell.Edge[] edges = Recurse.CalcEdgesSmart2(simplex.Facets, startingEdges.ToArray(), numEdges);
            //H3.Cell.Edge[] edges = Recurse.CalcEdges( simplex.Facets, startingEdges.ToArray(),
            //	new Recurse.Settings() { ThreshType = Recurse.EdgeThreshType.Radial, Threshold = H3Models.Ball.FindLocationForDesiredRadius( settings.PovRay.EdgeWidth, 0.8/100 ) } );
            //edges = edges.Where( e => e.Depths[0] % 2 == 1 ).ToArray();	// Used for Borromean Rings complement image.

            // Shapeways truncated 436.
            if (false)
            {
                if (true)
                {
                    Mobius m = Mobius.Scale(1.0 / H3Models.UHS.ToE(Honeycomb.InRadius(def.P, def.Q, def.R)));
                    double a = -Math.PI / 2 + Math.Asin(1 / Math.Sqrt(3));
                    edges = edges.Select(e =>
                    {
                        Vector3D v1 = e.Start;
                        Vector3D v2 = e.End;
                        v1.RotateAboutAxis(new Vector3D(1, 0, 0), a);
                        v2.RotateAboutAxis(new Vector3D(1, 0, 0), a);
                        v1 = H3Models.Ball.ApplyMobius(m, v1);
                        v2 = H3Models.Ball.ApplyMobius(m, v2);
                        return(new H3.Cell.Edge(v1, v2));
                    }).ToArray();

                    double   thresh  = -.01;
                    Vector3D looking = new Vector3D(0, 0, -1);
                    edges = edges.Where(e => e.Start.Dot(looking) > thresh && e.End.Dot(looking) > thresh).ToArray();

                    Dictionary <H3.Cell.Edge, int> edgeDict = edges.ToDictionary(e => e, e => 1);
                    H3.RemoveDanglingEdgesRecursive(edgeDict);
                    edges = edgeDict.Keys.ToArray();
                }
                else
                {
                    Mobius m = Mobius.Scale(2);
                    edges = edges.Select(e =>
                    {
                        Vector3D v1 = e.Start;
                        Vector3D v2 = e.End;
                        v1          = H3Models.Ball.ApplyMobius(m, v1);
                        v2          = H3Models.Ball.ApplyMobius(m, v2);
                        return(new H3.Cell.Edge(v1, v2));
                    }).ToArray();

                    Dictionary <H3.Cell.Edge, int> edgeDict = edges.ToDictionary(e => e, e => 1);
                    H3.RemoveDanglingEdgesRecursive(edgeDict);
                    edges = edgeDict.Keys.ToArray();
                }
            }

            //H3.m_settings.Output = H3.Output.STL;
            //H3.m_settings.Scale = 50;
            H3.SaveToFile(fileName, edges, finite: true, append: true);

            bool doCells = false;

            H3.Cell[] cellsToHighlight = null;
            if (doCells)
            {
                int[] polyMirrors = new int[] { 1, 2, 3 };
                active = active.Select(i => mapMirror(i)).OrderBy(i => i).ToArray();

                H3.Cell startingCell = PolyhedronToHighlight(Geometry.Hyperbolic, polyMirrors, simplex, startingPoint);
                cellsToHighlight = Recurse.CalcCells(simplex.Facets, new H3.Cell[] { startingCell });
                H3.AppendFacets(fileName, cellsToHighlight);
            }

            return(edges);
        }
Example #3
0
        public static void OneHoneycombGoursat(int[] active, string baseName, int baseHue, Settings settings = null)
        {
            // Setup parameters.
            int numEdges = 250000;

            if (settings != null)
            {
                active   = settings.PovRay.Active;
                numEdges = settings.PovRay.NumEdges;
                baseName = string.Join("-", settings.Angles);
            }

            CalcThickness(active);
            if (settings != null)
            {
                H3.m_settings.AngularThickness = settings.PovRay.EdgeWidth;                 // ZZZ - should really stop using that settings class.
            }
            // Create the simplex.
            Simplex simplex = new Simplex();

            if (settings != null)
            {
                simplex.InitializeGoursat(settings.Angles);
            }
            else
            {
                simplex.InitializeGoursat();
            }

            // Map of labels for mirrors consistent with input scheme to Goursat function.
            // Map is from wikipedia labeling scheme to the indices our function generates.
            //
            // wiki == our index
            // 0100 == 0
            // 0001 == 1
            // 1000 == 2
            // 0010 == 3
            Func <int, int> mapMirror = i =>
            {
                switch (i)
                {
                case 0: return(2);

                case 1: return(0);

                case 2: return(3);

                case 3: return(1);
                }
                throw new System.ArgumentException();
            };

            // We need to set this up before converting the mirrors.
            string mirrorsString = ActiveMirrorsString(active);
            string suffix        = "_" + mirrorsString;

            // Convert our active mirrors into the Goursat tet indices.
            int[] polyMirrors = new int[] { 1, 2, 3 };
            active      = active.Select(i => mapMirror(i)).OrderBy(i => i).ToArray();
            polyMirrors = polyMirrors.Select(i => mapMirror(i)).OrderBy(i => i).ToArray();

            Vector3D            startingPoint = IterateToStartingPoint(null, active, simplex);
            List <H3.Cell.Edge> startingEdges = new List <H3.Cell.Edge>();

            foreach (int a in active)
            {
                Vector3D reflected = simplex.ReflectInFacet(startingPoint, a);
                startingEdges.Add(new H3.Cell.Edge(startingPoint, reflected));
            }

            bool doEdges = true;
            bool doCells = false;

            // Generate the honeycomb.
            H3.Cell.Edge[] edges = null;
            if (doEdges)
            {
                edges = Recurse.CalcEdgesSmart(simplex.Facets, startingEdges.ToArray(), numEdges);
            }

            // Highlighted cells.
            H3.Cell[] cellsToHighlight = null;
            if (doCells)
            {
                H3.Cell startingCell = PolyhedronToHighlight(Geometry.Hyperbolic, polyMirrors, simplex, startingPoint);
                cellsToHighlight = Recurse.CalcCells(simplex.Facets, new H3.Cell[] { startingCell });
                //cellsToHighlight = new H3.Cell[] { startingCell };
            }

            // plugin Wendy's nonuniform calcs here...
            //Nonuniform.Wendy( simplex, edges );

            // Trim out half the edges (the ones we won't see in our Pov-Ray view).

            /*Vector3D lookFrom = new Vector3D( 1, 1, 1 ) * 0.7;
             * Vector3D lookAt = new Vector3D();   // pov-ray lookat
             * double thresh = -.01;
             * if( doEdges )
             *      edges = edges.Where( e => e.Start.Dot( lookAt ) > thresh || e.End.Dot( lookAt ) > thresh ).ToArray();
             * //if( doCells )
             * //	cellsToHighlight = cellsToHighlight.Where( c => c.Center.Dot( lookAt ) > thresh ).ToArray();	// I don't think this works right
             */

            string fileName = baseName + suffix;

            if (File.Exists(fileName + ".pov"))
            {
                File.Delete(fileName + ".pov");
                //Console.WriteLine( string.Format( "Skipping {0}", fileName ) );
                //return;
            }

            SetupBaseHueGoursat(fileName, mirrorsString, baseHue);

            if (doEdges)
            {
                H3.SaveToFile(fileName, edges, finite: true, append: true);
            }
            if (doCells)
            {
                HashSet <H3.Cell.Edge> cellEdges = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer());
                foreach (H3.Cell cell in cellsToHighlight)
                {
                    cell.AppendAllEdges(cellEdges);
                }
                edges = cellEdges.ToArray();
                H3.SaveToFile(fileName, edges, finite: true, append: true);

                H3.AppendFacets(fileName, cellsToHighlight);
            }
        }