Example #1
0
        internal static CoxeterImages.Settings AutoCalcScale(HoneycombDef def, Sphere[] mirrors)
        {
            // Calculate the color scale.
            int size = 200;

            CoxeterImages.Settings settings = new CoxeterImages.Settings()
            {
                Honeycomb = def,
                Width     = size,
                Height    = size,
                Bounds    = 1.1,
                Mirrors   = mirrors,
                FileName  = def.FormatFilename(),
            };

            CoxeterImages imageCalculator = new CoxeterImages();

            imageCalculator.AutoCalcScale(settings);
            if (settings.ColorScaling < 1)
            {
                settings.ColorScaling = 15;
            }

            return(settings);
        }
Example #2
0
        public static void DoStuff(Settings settings)
        {
            HoneycombDef imageData = new HoneycombDef(settings.P, settings.Q, settings.R);

            ////////////////////////////////////////////////////////////// Various things we've run over time.
            //Sandbox.CalcSelfSimilarityScale();
            //Sandbox.Check_pq_Distances();
            //HyperidealSquares();
            //S3.Hypercube();
            //R3.Geometry.Euclidean.GenEuclidean();
            //HoneycombGen.OneHoneycombOldCode();
            //AnimateCell( imageData );
            //CreateCellPovRay( imageData, "cell.pov" );
            //CreateSimplex( imageData );
            //HoneycombGen_old.OneHoneycombNew( new HoneycombDef() { P = imageData.P, Q = imageData.Q, R = imageData.R } );
            //SphericalAnimate( imageData );
            OneImage(settings);

            HoneycombDef[] scaleLarger = GetImageSet().Where(h =>
                                                             Geometry2D.GetGeometry(h.P, h.Q) == Geometry.Euclidean ||
                                                             Geometry2D.GetGeometry(h.P, h.Q) == Geometry.Spherical).ToArray();
            int count = scaleLarger.Length;
            //foreach( HoneycombAndView h in scaleLarger )
            //	Trace.WriteLine( h.FormatFilename() );

            //BatchRun( settings );
        }
Example #3
0
        public void AnimationSections(Settings config)
        {
            HoneycombDef imageData = new HoneycombDef(config.P, config.Q, config.R);
            int          p = imageData.P, q = imageData.Q, r = imageData.R;

            string filename = imageData.FormatFilename();

            Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r);
            double   bounds  = 1.0;          //config.UhsBoundary.Bounds;

            bounds = 9.0;

            // Calculate the color scale.
            int size = 200;

            CoxeterImages.Settings settings = new CoxeterImages.Settings()
            {
                Honeycomb = imageData,
                Width     = size,
                Height    = size,
                Bounds    = bounds,
                Mirrors   = mirrors,
                FileName  = imageData.FormatFilename(),
            };

            CoxeterImages imageCalculator = new CoxeterImages();

            //imageCalculator.AutoCalcScale( settings );
            if (settings.ColorScaling < 1)
            {
                settings.ColorScaling = 15;
            }
            settings.ColorScaling = 11;

            Program.Log("\nGenerating sections...");
            size              = 500;
            settings.Width    = size;
            settings.Height   = size;
            settings.FileName = filename;

            double max = Spherical2D.e2sNorm(15);
            double min = Spherical2D.e2sNorm(1.0 / 15);

            DonHatch.e2hNorm(max);
            int    numSteps = 1800;          // 1 minute
            double step     = (max - min) / numSteps;

            for (int i = 0; i < 1; i++)
            {
                Program.Log("\nSection " + i);
                imageCalculator.m_z = 1.0 / 0.5;
                Spherical2D.s2eNorm(min + step * i);
                DonHatch.h2eNorm(step * i);
                settings.FileName = string.Format("533_{0:D4}.png", i);
                imageCalculator.GenImage(settings);
            }
        }
Example #4
0
        /// <summary>
        /// The input time should lie in [0,1]
        /// </summary>
        /// <param name="t"></param>
        public static void ParacompactAnimationFrame(double t)
        {
            var def     = new HoneycombDef(4, 4, 4);
            var active  = new int[] { 1, 2 };
            int baseHue = -1;             // Black.

            //baseHue = 135;
            ViewPath.Time = t;
            OneHoneycombOrthoscheme(def, active, baseHue);
        }
Example #5
0
        public static void Create(HoneycombDef def, string filename)
        {
            int p = def.P;
            int q = def.Q;
            int r = def.R;

            double   scale = 5.0;
            Vector3D cen   = HoneycombPaper.InteriorPointBall;

            Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: false);

            // Apply transformations.
            simplex = simplex.Select(s =>
            {
                Sphere.ScaleSphere(s, scale);
                return(H3Models.UHSToBall(s));
            }).ToArray();

            for (int i = 0; i < 4; i++)
            {
                if (simplex[i].IsPointInside(cen))
                {
                    simplex[i].Invert = true;
                }
            }

            Sphere[] simplexForColorScale = SimplexCalcs.Mirrors(p, q, r, moveToBall: true);
            CoxeterImages.Settings temp   = HoneycombPaper.AutoCalcScale(def, simplexForColorScale);
            int maxDepth = (int)temp.ColorScaling;

            bool ball = true;
            bool dual = false;

            H3.Cell[] simplicesFinal = HoneycombPaper.GenCell(simplex, null, cen, ball, dual);

            simplicesFinal = simplicesFinal.Where(s => s.Depths[0] < 1).ToArray();
            //simplicesFinal = simplicesFinal.Where( s => s.)

            // Output the facets.
            using (StreamWriter sw = File.CreateText(filename))                 // We need to reuse this StreamWriter (vs. calling AppendSimplex) for performance.
            {
                sw.WriteLine("#include \"hyper_ball.pov\"");
                int[] include = new int[] { 0 };
                foreach (H3.Cell cell in simplicesFinal)
                {
                    Sphere[] facets = cell.Facets.Select(f => f.Sphere).ToArray();
                    int      depth  = cell.Depths[0] + 1;
                    Color    c      = Coloring.ColorAlongHexagon(maxDepth, depth);
                    PovRay.AddSimplex(sw, facets, cell.Center, include, filename, Coloring.ToVec(c));
                }
            }
        }
Example #6
0
        private static void SphericalAnimate(HoneycombDef imageData)
        {
            double colorScaling = AnimColorScaling(imageData);

            //int fps = 30;
            //int frames = 60 * fps;
            int frames = 5;

            for (int i = 0; i < frames; i++)
            {
                double t        = (double)i / frames;
                string filename = "batch/" + imageData.FormatFilename(string.Empty) + FrameString(i) + ".png";
                OneAnimationFrame(imageData, filename, colorScaling, t);
            }
        }
Example #7
0
        private static void AnimateCell(HoneycombDef imageData)
        {
            int numFrames = 100;

            for (int i = 0; i < numFrames; i++)
            {
                double t        = (double)i / numFrames;
                string filename = "batch/cell" + FrameString(i) + ".pov";
                Console.WriteLine(filename);

                System.IO.File.Delete(filename);
                using (StreamWriter sw = new StreamWriter(filename))
                    sw.WriteLine("#include \"C:\\Users\\hrn\\Documents\\roice\\povray\\H3\\horosphere\\633.pov\"");

                CreateCellPovRay(imageData, filename, t);
            }
        }
Example #8
0
        public static void OneImage(Settings config, double t = 0.0)
        {
            HoneycombDef imageData = new HoneycombDef(config.P, config.Q, config.R);
            int          p = imageData.P, q = imageData.Q, r = imageData.R;

            string filename = imageData.FormatFilename();

            //if( File.Exists( filename ) )
            //	return;

            Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r);
            double   bounds  = config.UhsBoundary.Bounds;

            // Calculate the color scale.
            int size = 200;

            CoxeterImages.Settings settings = new CoxeterImages.Settings()
            {
                Honeycomb = imageData,
                Width     = size,
                Height    = size,
                Bounds    = bounds,
                Mirrors   = mirrors,
                FileName  = imageData.FormatFilename(),
            };

            CoxeterImages imageCalculator = new CoxeterImages();

            imageCalculator.AutoCalcScale(settings);
            if (settings.ColorScaling < 1)
            {
                settings.ColorScaling = 15;
            }

            Program.Log("\nGenerating full image...");
            size              = 500;
            settings.Width    = config.UhsBoundary.ImageWidth;
            settings.Height   = config.UhsBoundary.ImageHeight;
            settings.FileName = filename;
            imageCalculator.GenImage(settings, t);
        }
Example #9
0
        private static void CreateSimplex(HoneycombDef imageData)
        {
            int p = imageData.P;
            int q = imageData.Q;
            int r = imageData.R;

            Vector3D cen  = InteriorPointBall;
            bool     ball = true;

            Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, ref cen, moveToBall: ball);

            // Offset as we do for the boundary images.
            //Sphere s = H3Models.UHSToBall( simplex[0] );
            //s = CoxeterImages.GeodesicOffset( s, 0.02, ball: true );

            if (m_toKlein)
            {
                simplex = simplex.Select(s => H3Models.BallToKlein(s)).ToArray();
            }

            int[] include = new int[] { 0, 1, 2, 3 };                   // All facets
            //int[] include = new int[] { 1 };
            File.Delete("simplex.pov");
            PovRay.AppendSimplex(simplex, cen, include, "simplex.pov");

            bool includeEdges = false;

            if (includeEdges)
            {
                H3.Cell.Edge[] edges = SimplexCalcs.SimplexEdgesUHS(p, q, r);
                PovRay.WriteEdges(new PovRay.Parameters {
                    Halfspace = true, AngularThickness = 0.03
                },
                                  Geometry.Hyperbolic, edges, "simplex.pov", append: true);
            }
        }
Example #10
0
        private static void OneAnimationFrame(HoneycombDef imageData, string filename, double colorScaling, double t = 0.0)
        {
            int p = imageData.P, q = imageData.Q, r = imageData.R;

            Sphere[] mirrors = SimplexCalcs.Mirrors(p, q, r);

            int size = 750;

            size = 1024;
            CoxeterImages.Settings settings = new CoxeterImages.Settings()
            {
                Honeycomb = imageData,
                Width     = size * 2,
                Height    = size,
                Bounds    = 1.0,
                Mirrors   = mirrors,
                FileName  = filename,
            };

            CoxeterImages imageCalculator = new CoxeterImages();

            settings.ColorScaling = colorScaling;
            imageCalculator.GenImage(settings, t);
        }
Example #11
0
        // CHEAT! (would be better to do a geometrical construction)
        // We are going to iterate to the starting point that will make all edge lengths the same.
        public static Vector3D IterateToStartingPoint(HoneycombDef?def, int[] activeMirrors, Simplex simplex)
        {
            if (activeMirrors.Length == 1)
            {
                return(simplex.Verts[activeMirrors[0]]);
            }

            // We are minimizing the output of this function,
            // because we want all edge lengths to be as close as possible.
            // Input vector should be in the Ball Model.
            Func <Vector3D, double> diffFunc = v =>
            {
                List <double> lengths = new List <double>();
                for (int i = 0; i < activeMirrors.Length; i++)
                {
                    Vector3D reflected = simplex.ReflectInFacet(v, activeMirrors[i]);
                    lengths.Add(H3Models.Ball.HDist(v, reflected));
                }

                double result  = 0;
                double average = lengths.Average();
                foreach (double length in lengths)
                {
                    result += Math.Abs(length - average);
                }
                if (Infinity.IsInfinite(result))
                {
                    result = double.PositiveInfinity;
                }
                return(result);
            };

            // So that we can leverage Euclidean barycentric coordinates, we will first convert our simplex to the Klein model.
            // We will need to take care to properly convert back to the Ball as needed.
            Vector3D[] kleinVerts = simplex.Verts.Select(v => HyperbolicModels.PoincareToKlein(v)).ToArray();
            if (def != null)
            {
                HoneycombDef d = def.Value;
                Geometry     vertexGeometry = Geometry2D.GetGeometry(d.Q, d.R);
                if (vertexGeometry == Geometry.Hyperbolic)
                {
                    kleinVerts[3] = SimplexCalcs.VertexPointKlein(d.P, d.Q, d.R);
                }
            }

            // Normalizing barycentric coords amounts to making sure the 4 coords add to 1.
            Func <Vector3D, Vector3D> baryNormalize = b =>
            {
                return(b / (b.X + b.Y + b.Z + b.W));
            };

            // Bary Coords to Euclidean
            Func <Vector3D[], Vector3D, Vector3D> baryToEuclidean = (kv, b) =>
            {
                Vector3D result =
                    kv[0] * b.X + kv[1] * b.Y + kv[2] * b.Z + kv[3] * b.W;
                return(result);
            };

            // Our starting barycentric coords (halfway between all active mirrors).
            Vector3D bary = new Vector3D();

            foreach (int a in activeMirrors)
            {
                bary[a] = 0.5;
            }
            bary = baryNormalize(bary);

            // For each iteration, we'll shrink this search offset.
            // NOTE: The starting offset and decrease factor I'm using don't guarantee convergence,
            // but it seems to be working pretty well (even when varying these parameters).
            //double searchOffset = 1.0 - bary[activeMirrors[0]];
            //double searchOffset = bary[activeMirrors[0]];
            double factor       = 1.5;          // Adjusting this helps get some to converge, e.g. 4353-1111
            double searchOffset = bary[activeMirrors[0]] / factor;

            double min        = double.MaxValue;
            int    iterations = 1000;

            for (int i = 0; i < iterations; i++)
            {
                min = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, bary)));
                foreach (int a in activeMirrors)
                {
                    Vector3D baryTest1 = bary, baryTest2 = bary;
                    baryTest1[a] += searchOffset;
                    baryTest2[a] -= searchOffset;
                    baryTest1     = baryNormalize(baryTest1);
                    baryTest2     = baryNormalize(baryTest2);

                    double t1 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest1)));
                    double t2 = diffFunc(HyperbolicModels.KleinToPoincare(baryToEuclidean(kleinVerts, baryTest2)));
                    if (t1 < min)
                    {
                        min  = t1;
                        bary = baryTest1;
                    }
                    if (t2 < min)
                    {
                        min  = t2;
                        bary = baryTest2;
                    }
                }

                if (Tolerance.Equal(min, 0.0, 1e-14))
                {
                    System.Console.WriteLine(string.Format("Converged in {0} iterations.", i));
                    break;
                }

                searchOffset /= factor;
            }

            if (!Tolerance.Equal(min, 0.0, 1e-14))
            {
                System.Console.WriteLine("Did not converge: " + min);

                // Be a little looser before thrown an exception.
                if (!Tolerance.Equal(min, 0.0, 1e-12))
                {
                    System.Console.ReadKey(true);
                    //throw new System.Exception( "Boo. We did not converge." );
                    return(Vector3D.DneVector());
                }
            }

            Vector3D euclidean = baryToEuclidean(kleinVerts, bary);

            return(HyperbolicModels.KleinToPoincare(euclidean));
        }
Example #12
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 #13
0
 private static string BaseName(HoneycombDef def)
 {
     return(string.Format("{0}-{1}-{2}", def.P, def.Q, def.R));
 }
Example #14
0
        public static void ParacompactSet()
        {
            List <int[]> toRun = new List <int[]>();

            toRun.Add(new int[] { 0, 1 });
            toRun.Add(new int[] { 0, 2 });
            toRun.Add(new int[] { 0, 3 });
            toRun.Add(new int[] { 1, 2 });
            toRun.Add(new int[] { 1, 3 });
            toRun.Add(new int[] { 2, 3 });
            toRun.Add(new int[] { 0, 1, 2 });
            toRun.Add(new int[] { 0, 1, 3 });
            toRun.Add(new int[] { 0, 2, 3 });
            toRun.Add(new int[] { 1, 2, 3 });
            toRun.Add(new int[] { 0, 1, 2, 3 });

            //toRun.Clear();
            //toRun.Add( new int[] { 0, 1, 3 } );

            int          baseHue = 0;
            HoneycombDef def;

            baseHue = 135;
            def     = new HoneycombDef(6, 3, 3);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }

            baseHue = 220;
            def     = new HoneycombDef(6, 3, 4);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }

            baseHue = 180;
            def     = new HoneycombDef(6, 3, 5);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }

            baseHue = 255;
            def     = new HoneycombDef(6, 3, 6);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }

            baseHue = 105;
            def     = new HoneycombDef(3, 6, 3);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }

            baseHue = 300;
            def     = new HoneycombDef(4, 4, 3);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }

            baseHue = 0;
            def     = new HoneycombDef(4, 4, 4);
            foreach (int[] active in toRun)
            {
                OneHoneycombOrthoscheme(def, active, baseHue);
            }
        }
Example #15
0
        private static void HoneycombFiniteVertexFig(HoneycombDef def, int lod, Dictionary <Vector3D, H3.Cell> complete)
        {
            int p = def.P;
            int q = def.Q;
            int r = def.R;

            double   scale = 1.0;
            Vector3D vUHS  = H3Models.BallToUHS(SimplexCalcs.VertexPointBall(p, q, r));

            if (Geometry2D.GetGeometry(q, r) != Geometry.Hyperbolic)                // Vertex-centered if possible
            {
                scale = 1.0 / vUHS.Z;
            }
            System.Func <Vector3D, Vector3D> trans = v =>
            {
                v  = H3Models.BallToUHS(v);
                v *= scale;
                v  = H3Models.UHSToBall(v);
                return(v);
            };

            bool ball = true;

            Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: ball);
            simplex = simplex.Select(s =>
            {
                s = H3Models.BallToUHS(s);
                Sphere.ScaleSphere(s, scale);
                s = H3Models.UHSToBall(s);
                return(s);
            }).ToArray();
            H3.Cell.Edge[] edges = SimplexCalcs.SimplexEdgesBall(p, q, r);

            // Two edges of the simplex facet.
            // NOTE: This contruction only works for material triangles, and matches the construction in the TextureHelper.
            m_div = TextureHelper.SetLevels(lod);
            int[]           elementIndices = TextureHelper.TextureElements(1, lod);
            List <Vector3D> points         = new List <Vector3D>();

            H3.Cell.Edge e1 = edges[2];
            H3.Cell.Edge e2 = edges[3];
            Vector3D     p1 = trans(e1.Start), p2 = trans(e1.End), p3 = trans(e2.End);

            Vector3D[] points1 = H3Models.Ball.GeodesicPoints(p2, p1, m_div);
            Vector3D[] points2 = H3Models.Ball.GeodesicPoints(p3, p1, m_div);
            for (int i = 0; i < m_div; i++)
            {
                points.AddRange(H3Models.Ball.GeodesicPoints(points1[i], points2[i], m_div - i));
            }
            points.Add(p1);

            Mesh mesh = new Mesh();

            for (int i = 0; i < elementIndices.Length / 3; i++)
            {
                int      idx1 = i * 3;
                int      idx2 = i * 3 + 1;
                int      idx3 = i * 3 + 2;
                Vector3D v1   = points[elementIndices[idx1]];
                Vector3D v2   = points[elementIndices[idx2]];
                Vector3D v3   = points[elementIndices[idx3]];
                mesh.Triangles.Add(new Mesh.Triangle(v1, v2, v3));
            }

            // AuxPoints will be used for multiple things.
            // - The first is a definition point for a face, so we can check for duplicates.
            // - We'll also store the points for the 3 edges of our fundamental triangle.
            List <Vector3D> auxPoints = new List <Vector3D>();
            {
                auxPoints.Add((p1 + p2 + p3) / 3);
                auxPoints.AddRange(points1);
                auxPoints.AddRange(points2.Reverse());
                auxPoints.AddRange(H3Models.Ball.GeodesicPoints(points2[0], points1[0], m_div));
            }

            Vector3D cen = HoneycombPaper.InteriorPointBall;

            H3.Cell[] simplices = GenCell(simplex, mesh, cen, auxPoints.ToArray(), ball);

            // Existing cells take precedence.
            foreach (H3.Cell c in simplices)
            {
                Vector3D t = c.AuxPoints[0];
                H3.Cell  dummy;
                if (!complete.TryGetValue(t, out dummy))
                {
                    complete[t] = c;
                }
            }
        }
Example #16
0
        public static void Test()
        {
            HoneycombDef def     = new HoneycombDef(5, 3, 4);
            Simplex      simplex = new Simplex();

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

            // Simplices will be the "cells"
            H3.Cell.Facet[] simplexFacets = simplex.Facets.Select(m => new H3.Cell.Facet(m)).ToArray();
            H3.Cell         startingCell  = new H3.Cell(simplexFacets);
            startingCell.AuxPoints = SimplexCalcs.VertsBall(def.P, def.Q, def.R);
            startingCell.Center    = HoneycombPaper.InteriorPointBall;

            var cells = CalcCells(simplex.Facets, new H3.Cell[] { startingCell });

            // Get all the cell centers
            HashSet <Vector3D> centers = new HashSet <Vector3D>();

            foreach (var cell in cells)
            {
                Vector3D cellCen = cell.AuxPoints[0];
                centers.Add(cellCen);
            }

            // Colors.
            Dictionary <double, Color> colors = new Dictionary <double, Color>(new DoubleEqualityComparer());

            System.Random rand = new System.Random(0);

            // Get all the in-spheres
            double inRad = startingCell.AuxPoints[1].Abs();
            //inRad *= 1.16;
            List <Sphere> inSpheres = new List <Sphere>();

            foreach (Vector3D c in centers)
            {
                Vector3D p = c;
                //SphericalModels.GnomonicToStereo( c );
                Geometry g = Geometry.Hyperbolic;

                Vector3D cen;
                double   rad;
                H3Models.Ball.DupinCyclideSphere(p, inRad, g, out cen, out rad);
                Sphere i = new Sphere(cen, rad);

                Color color;
                if (!colors.TryGetValue(c.Abs(), out color))
                {
                    Vector3D rgb = ColorUtil.CHSL2RGB(new Vector3D(rand.NextDouble() * 360, .5, .5));
                    rgb            *= 255;
                    color           = Color.FromArgb(255, (int)rgb.X, (int)rgb.Y, (int)rgb.Z);
                    colors[c.Abs()] = color;
                }
                i.Color = color;

                inSpheres.Add(i);
            }

            // Project sphere to unit sphere.
            List <Circle3D> circlesOnUnitSphere = new List <Circle3D>();

            foreach (Sphere i in inSpheres)
            {
                if (i.Center.IsOrigin || i.Center.DNE || Infinity.IsInfinite(i.Center))
                {
                    continue;
                }

                Sphere   orthogonal = new Sphere(new Vector3D(), RadiusOrthogonal(i));
                Circle3D c          = orthogonal.Intersection(i);

                // We need to scale this based on the size of the orthogonal sphere.
                c.Center /= orthogonal.Radius;
                c.Radius /= orthogonal.Radius;
                c.Color   = i.Color;
                circlesOnUnitSphere.Add(c);
            }
            Circle3D unit = new Circle3D();

            //circlesOnUnitSphere.Add( unit );

            ProjectAndSave(circlesOnUnitSphere);
        }
Example #17
0
        public static void HoneycombHyperidealLegs(HoneycombDef def)
        {
            // This will be used to avoid duplicates.
            // The key is the cell center.
            Dictionary <Vector3D, H3.Cell> complete = new Dictionary <Vector3D, H3.Cell>();

            m_thresh = 0.05;
            //m_thresh = 0.07;
            HoneycombHyperidealLegs(def, 3, complete);

            m_thresh = 0.01;
            //m_thresh = 0.02;
            HoneycombHyperidealLegs(def, 2, complete);

            m_thresh = 0.004;
            //m_thresh = 0.007;
            HoneycombHyperidealLegs(def, 1, complete);

            string filename = "cell.stl";

            System.IO.File.Delete(filename);
            using (StreamWriter sw = File.AppendText(filename))
            {
                HashSet <H3.Cell.Edge> edgesToMesh = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer());
                foreach (H3.Cell cell in complete.Values)
                {
                    int depth = cell.Depths.Sum();

                    Mesh   m      = new Mesh();
                    Sphere normal = cell.Facets[0].Sphere;
                    foreach (Mesh.Triangle tri in cell.Mesh.Triangles)
                    {
                        Mesh.Triangle[] thickened = Thicken(tri, normal);
                        m.Triangles.AddRange(thickened.Select(t => Transform(t)));
                    }

                    List <object> boundary = new List <object>();
                    int           skip     = 2;
                    int           stride   = (int)Math.Sqrt(cell.Mesh.Triangles.Count) / 2 + 1;
                    int           num      = stride;
                    boundary.Add(cell.AuxPoints.Skip(skip).Take(num));
                    skip += num;
                    boundary.Add(cell.AuxPoints.Skip(skip).Take(num));
                    skip += num;
                    num   = 2 * m_div + 1;
                    boundary.Add(cell.AuxPoints.Skip(skip).Take(num));
                    skip += num;
                    boundary.Add(cell.AuxPoints.Skip(skip).Take(num));
                    skip += num;
                    foreach (object e in boundary)
                    {
                        var enumerable = (IEnumerable <Vector3D>)e;
                        //if( depth % 2 == 0 )
                        //	enumerable = enumerable.Reverse();

                        Mesh m2 = ThickenBoundary(enumerable.ToArray(), normal);

                        if (depth % 2 == 0)
                        {
                            ReverseTris(m2);
                        }

                        m.Triangles.AddRange(m2.Triangles.Select(t => Transform(t)));
                    }

                    STL.AppendMeshToSTL(m, sw);
                    edgesToMesh.Add(new H3.Cell.Edge(cell.AuxPoints[0], cell.AuxPoints[1]));
                }

                /*foreach( H3.Cell.Edge e in edgesToMesh )
                 * {
                 *      Mesh m3 = new Mesh();
                 *      AddEdge( m3, Transform( e.Start ), Transform( e.End ) );
                 *      STL.AppendMeshToSTL( m3, sw );
                 * }*/
            }
        }
Example #18
0
        /// <summary>
        /// Create an STL file for a cell.
        /// Currently only works for cells with both hyperideal vertices and cells.
        /// </summary>
        public static void HoneycombHyperidealLegs(HoneycombDef def, int lod, Dictionary <Vector3D, H3.Cell> complete)
        {
            int p = def.P;
            int q = def.Q;
            int r = def.R;

            m_div = TextureHelper.SetLevels(lod);

            bool ball = false;

            Sphere[]       simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: ball);
            H3.Cell.Edge[] edges;
            if (ball)
            {
                edges = SimplexCalcs.SimplexEdgesBall(p, q, r);
            }
            else
            {
                edges = SimplexCalcs.SimplexEdgesUHS(p, q, r);
            }

            // Two edges of one simplex facet.
            H3.Cell.Edge e1 = edges[2];
            H3.Cell.Edge e2 = edges[3];
            Vector3D[]   points1, points2;
            if (ball)
            {
                points1 = H3Models.Ball.GeodesicPoints(e1.Start, e1.End, 2 * m_div);
                points2 = H3Models.Ball.GeodesicPoints(e2.Start, e2.End, 2 * m_div);
            }
            else
            {
                points1 = H3Models.UHS.GeodesicPoints(e1.Start, e1.End, 2 * m_div);
                points2 = H3Models.UHS.GeodesicPoints(e2.Start, e2.End, 2 * m_div);
            }

            Sphere cellSphere   = simplex[0];
            Sphere vertexSphere = simplex[3];

            // Because one vertex the facet triangle is hyperideal, it will actually look like a square.
            List <Vector3D[]> allPoints = new List <Vector3D[]>();

            for (int i = 0; i < points1.Length; i++)
            {
                Vector3D p1 = points1[i];
                Vector3D p2 = points2[i];

                Vector3D[] arcPoints;
                if (i == points1.Length - 1)
                //if( false )
                {
                    // NOTE: This arc is not generally geodesic!
                    // Or is it?
                    arcPoints = ball ?
                                H3Models.Ball.GeodesicPoints(p1, p2, m_div) :
                                H3Models.UHS.GeodesicPoints(p1, p2, m_div);

                    /*Circle3D arc = cellSphere.Intersection( vertexSphere );
                     * double angleTot = (p1 - arc.Center).AngleTo( p2 - arc.Center );
                     * arcPoints = Shapeways.CalcArcPoints( arc.Center, arc.Radius, p1, arc.Normal, -angleTot, div );*/
                }
                else
                {
                    Circle3D c        = Circle3D.FromCenterAnd2Points(cellSphere.Center, p1, p2);
                    double   angleTot = (p1 - c.Center).AngleTo(p2 - c.Center);
                    arcPoints = Shapeways.CalcArcPoints(cellSphere.Center, cellSphere.Radius, p1, c.Normal, -angleTot, m_div);
                }
                //Vector3D[] arcPoints = new Vector3D[] { p1, p2 };
                allPoints.Add(arcPoints);
            }

            // Create the triangles for the patch.
            Mesh mesh = new Mesh();

            for (int i = 0; i < allPoints.Count - 1; i++)
            {
                Vector3D[] arc1 = allPoints[i];
                Vector3D[] arc2 = allPoints[i + 1];

                for (int j = 0; j < arc1.Length - 1; j++)
                {
                    // Points of (i,j) box;
                    Vector3D p1 = arc1[j];
                    Vector3D p2 = arc2[j];
                    Vector3D p3 = arc1[j + 1];
                    Vector3D p4 = arc2[j + 1];

                    Mesh.Triangle tri1 = new Mesh.Triangle(p1, p2, p3);
                    Mesh.Triangle tri2 = new Mesh.Triangle(p2, p4, p3);

                    // We need to thicken after reflecting around, otherwise we can't apply a min thickness.

                    /*Sphere normal = cellSphere;
                     * Mesh.Triangle[] thickened1 = Thicken( tri1, normal );
                     * Mesh.Triangle[] thickened2 = Thicken( tri2, normal );
                     * mesh.Triangles.AddRange( thickened1 );
                     * mesh.Triangles.AddRange( thickened2 );*/

                    mesh.Triangles.Add(tri1);
                    mesh.Triangles.Add(tri2);
                }
            }

            // AuxPoints will be used for multiple things.
            // - The first two points are for an an that will fill the gap where there is a missing face.
            // - We'll also store the points for the 4 edges of our fundamental triangle.
            List <Vector3D> auxPoints = new List <Vector3D>();
            {
                var             edge1 = allPoints.First();
                var             edge2 = allPoints.Last();
                List <Vector3D> edge3 = new List <Vector3D>(), edge4 = new List <Vector3D>();
                for (int i = 0; i < allPoints.Count; i++)
                {
                    edge3.Add(allPoints[i][0]);
                    edge4.Add(allPoints[i][allPoints[i].Length - 1]);
                }
                edge4.Reverse();

                auxPoints.Add(e1.Start);
                auxPoints.Add(e1.End);
                auxPoints.AddRange(edge1.Reverse());
                auxPoints.AddRange(edge2);
                auxPoints.AddRange(edge3);
                auxPoints.AddRange(edge4);
            }

            Vector3D cen = HoneycombPaper.InteriorPointBall;

            /* Reorientation code.  Move this elsewhere.
             *
             * // Face centered orientation.
             * bool faceCentered = false;
             * if( faceCentered )
             *      SimplexCalcs.PrepForFacetCentering( p, q, simplex, ref cen );
             *
             * Mobius mUHS = SimplexCalcs.FCOrientMobius( p, q );
             * Mobius mBall = HoneycombPaper.FCOrientMobius( H3Models.UHSToBall( cellSphere ) );
             *
             * simplex = simplex.Select( s =>
             * {
             *      s = H3Models.UHSToBall( s );
             *      //H3Models.TransformInBall2( s, mBall );
             *      return s;
             * } ).ToArray();
             *
             *
             * {
             *      for( int i = 0; i < mesh.Triangles.Count; i++ )
             *      {
             *              Mesh.Triangle tri = mesh.Triangles[i];
             *
             *              if( faceCentered )
             *              {
             *                      tri.a = mUHS.ApplyToQuaternion( tri.a );
             *                      tri.b = mUHS.ApplyToQuaternion( tri.b );
             *                      tri.c = mUHS.ApplyToQuaternion( tri.c );
             *              }
             *
             *              tri.a = H3Models.UHSToBall( tri.a );
             *              tri.b = H3Models.UHSToBall( tri.b );
             *              tri.c = H3Models.UHSToBall( tri.c );
             *
             *              if( faceCentered )
             *              {
             *                      tri.a = H3Models.TransformHelper( tri.a, mBall );
             *                      tri.b = H3Models.TransformHelper( tri.b, mBall );
             *                      tri.c = H3Models.TransformHelper( tri.c, mBall );
             *              }
             *              mesh.Triangles[i] = tri;
             *      }
             *
             *      if( faceCentered )
             *              cen = H3Models.TransformHelper( cen, mBall );
             * }
             */

            // Now we need to reflect around this fundamental patch.
            H3.Cell[] simplices = GenCell(simplex, mesh, cen, auxPoints.ToArray(), ball);

            // Existing cells take precedence.
            foreach (H3.Cell c in simplices)
            {
                Vector3D t = c.Center;
                H3.Cell  dummy;
                if (!complete.TryGetValue(t, out dummy))
                {
                    complete[t] = c;
                }
            }
        }
Example #19
0
        private static void CreateCellPovRay(HoneycombDef def, string filename, double t = 0)
        {
            int p = def.P;
            int q = def.Q;
            int r = def.R;

            //Vector3D trans = new Vector3D( 1.0/3, 0 ) * (2 + 2 * Math.Sin( Math.PI / 6 )) * t;
            //double scale = 1.8;
            Vector3D trans = new Vector3D();
            double   scale = 1.0;

            Vector3D[] sVerts = null;               // SimplexCalcs.VertsBall( p, q, r );

            Vector3D vUHS = H3Models.BallToUHS(SimplexCalcs.VertexPointBall(p, q, r));

            // Just did this for everything.  Non-general position working better and will make all heads consistent.
            scale = 2.0;

            if (Geometry2D.GetGeometry(q, r) != Geometry.Hyperbolic)                // Vertex-centered if possible
            {
                scale = 1.0 / vUHS.Z;
            }
            //else if( Geometry2D.GetGeometry( p, q ) == Geometry.Hyperbolic ) // Make the biggest head somewhat smaller.
            //	scale = 2.0;

            Vector3D cen = InteriorPointBall;

            /*var kleinVerts = sVerts.Select( v => HyperbolicModels.PoincareToKlein( v ) );
             * Vector3D avg = new Vector3D();
             * foreach( Vector3D v in kleinVerts )
             *      avg += v;
             * avg /= kleinVerts.Count();
             * Vector3D cen = HyperbolicModels.KleinToPoincare( avg );*/
            cen  = H3Models.BallToUHS(cen);
            cen += trans;
            //cen *= scale;
            cen = H3Models.UHSToBall(cen);

            Sphere[] simplex = SimplexCalcs.Mirrors(p, q, r, moveToBall: false);

            // Apply transformations.
            simplex = simplex.Select(s =>
            {
                Sphere.TranslateSphere(s, trans);
                Sphere.ScaleSphere(s, scale);
                return(H3Models.UHSToBall(s));
            }).ToArray();

            for (int i = 0; i < 4; i++)
            {
                if (simplex[i].IsPointInside(cen))
                {
                    simplex[i].Invert = true;
                }
            }

            Sphere[] simplexForColorScale = SimplexCalcs.Mirrors(p, q, r, moveToBall: true);
            CoxeterImages.Settings temp   = AutoCalcScale(def, simplexForColorScale);
            int maxDepth = (int)temp.ColorScaling;
            //Random rand = new Random( p+q+r );
            //int randOffset = rand.Next( maxDepth );

            bool ball = true;
            bool dual = false;

            H3.Cell[] simplicesFinal = GenCell(simplex, null, cen, ball, dual);

            using (StreamWriter sw = File.CreateText(filename))                 // We need to reuse this StreamWriter (vs. calling AppendSimplex) for performance.
            {
                sw.WriteLine("#include \"hyper_ball.pov\"");

                //int[] include = new int[] { 0, 1, 2, 3 };
                int[] include = new int[] { 0 };
                if (dual)
                {
                    include = new int[] { 3 }
                }
                ;

                // Output the facets.
                foreach (H3.Cell cell in simplicesFinal)
                {
                    Sphere[] facets = cell.Facets.Select(f => f.Sphere).ToArray();
                    if (m_toKlein)
                    {
                        facets = facets.Select(s => H3Models.BallToKlein(s)).ToArray();
                    }

                    int   depth = cell.Depths[0] + 1;
                    Color c     = Coloring.ColorAlongHexagon(maxDepth, depth);
                    if (cell.Depths.Sum() % 2 == 0)
                    {
                        c = Coloring.Inverse(c);
                    }
                    PovRay.AddSimplex(sw, facets, cell.Center, include, filename, Coloring.ToVec(c));
                }

                /*include = new int[] { 1, 2, 3 };
                 * foreach( H3.Cell cell in simplicesFinal )
                 * {
                 *      Sphere[] facets = cell.Facets.Select( f => f.Sphere ).ToArray();
                 *      Color c = Color.Red;
                 *      Vector3D cv = Coloring.ToVec( c );
                 *      cv.W = 0.9;
                 *      PovRay.AddSimplex( sw, facets, cell.Center, include, filename, cv );
                 * }*/
            }

            // Output the edges/verts.
            bool includeEdges = false;

            if (includeEdges)
            {
                sVerts = sVerts.Select(v =>
                {
                    v  = H3Models.BallToUHS(v);
                    v += trans;
                    v *= scale;
                    return(H3Models.UHSToBall(v));
                }).ToArray();

                H3.Cell.Edge[] edges = Recurse.CalcEdges(simplex.Skip(1).ToArray(),
                                                         new H3.Cell.Edge[] { new H3.Cell.Edge(sVerts[2], sVerts[3], order: false) },
                                                         new Recurse.Settings()
                {
                    Threshold = 0.01
                });
                PovRay.WriteH3Edges(new PovRay.Parameters {
                    AngularThickness = 0.01
                }, edges, filename, append: true);

                HashSet <Vector3D> verts = new HashSet <Vector3D>();
                foreach (H3.Cell.Edge e in edges)
                {
                    verts.Add(e.End);
                }
                PovRay.WriteVerts(new PovRay.Parameters {
                    AngularThickness = 0.02
                }, Geometry.Hyperbolic, verts.ToArray(), filename, append: true);
            }
        }
Example #20
0
        public static void HoneycombFiniteVertexFig(HoneycombDef def)
        {
            // This will be used to remove duplicates.
            // Our faces will be doubled-up.  We'll make a hash from one of the interior meshPoints.
            Dictionary <Vector3D, H3.Cell> complete = new Dictionary <Vector3D, H3.Cell>();

            m_thresh = 0.07;
            HoneycombFiniteVertexFig(def, 3, complete);

            m_thresh = 0.02;
            HoneycombFiniteVertexFig(def, 2, complete);

            m_thresh = 0.007;
            HoneycombFiniteVertexFig(def, 1, complete);

            //m_thresh = 0.005;
            //CreateHoneycombSTL( def, 0, complete );

            string filename = "cell.stl";

            System.IO.File.Delete(filename);
            using (StreamWriter sw = File.AppendText(filename))
            {
                foreach (H3.Cell cell in complete.Values)
                {
                    //STL.AppendMeshToSTL( cell.Mesh, sw );

                    bool reverse = cell.Depths.Sum() % 2 == 1;

                    Mesh   m      = new Mesh();
                    Sphere normal = cell.Facets[0].Sphere;
                    foreach (Mesh.Triangle tri in cell.Mesh.Triangles)
                    {
                        Mesh.Triangle[] thickened = ThickenSimple(tri, normal);
                        m.Triangles.AddRange(thickened);
                    }

                    if (reverse)
                    {
                        ReverseTris(m);
                    }

                    STL.AppendMeshToSTL(m, sw);

                    System.Func <Vector3D, System.Tuple <Vector3D, Vector3D> > thickenFn = v => ThickenSimple(v, normal);
                    int        stride = (int)Math.Sqrt(cell.Mesh.Triangles.Count) + 1;
                    Vector3D[] e1 = cell.AuxPoints.Skip(1 + 0 * stride).Take(stride).ToArray();
                    Vector3D[] e2 = cell.AuxPoints.Skip(1 + 1 * stride).Take(stride).ToArray();
                    Vector3D[] e3 = cell.AuxPoints.Skip(1 + 2 * stride).Take(stride).ToArray();
                    Mesh       m1 = ThickenBoundary(e1, thickenFn), m2 = ThickenBoundary(e2, thickenFn), m3 = ThickenBoundary(e3, thickenFn);
                    if (reverse)
                    {
                        ReverseTris(m1);
                        ReverseTris(m2);
                        ReverseTris(m3);
                    }

                    STL.AppendMeshToSTL(m1, sw);
                    STL.AppendMeshToSTL(m2, sw);
                    STL.AppendMeshToSTL(m3, sw);
                }
            }
        }
Example #21
0
 private static double AnimColorScaling(HoneycombDef imageData)
 {
     return(10);
 }
Example #22
0
        /// <summary>
        /// This generates a honeycomb by reflecting in 4 mirrors of the fundamental simplex.
        /// This "new" method is now old.
        /// </summary>
        public static void OneHoneycombNew(HoneycombDef imageData)
        {
            int p = imageData.P;
            int q = imageData.Q;
            int r = imageData.R;

            double thickness           = 0.05;
            double thicknessSpherical  = Spherical2D.s2eNorm(thickness);
            double thicknessHyperbolic = R3.Math.DonHatch.h2eNorm(thickness);
            double threshold           = 1;

            H3.Cell.Edge[] edges            = null;
            H3.Cell[]      cellsToHighlight = null;
            Sphere[]       simplex          = null;
            Vector3D       vertex           = new Vector3D();

            Geometry g = Util.GetGeometry(p, q, r);

            if (g == Geometry.Spherical)
            {
                thickness = thicknessSpherical /*.07 for 333*/  /* 0.05for 433*/  /*.025 for 533,335*/;
                threshold = 10000;

                simplex = SimplexCalcs.MirrorsSpherical(p, q, r);
                vertex  = SimplexCalcs.VertexSpherical(p, q, r);

                // Ugly special casing for 333, since it has a vertex project to infinity.
                if (p == 3 && q == 3 && r == 3)
                {
                    SpecialCase333();
                }
            }
            else if (g == Geometry.Euclidean)
            {
                thickness = thickness / 2;
                threshold = 1 /*20*/;

                //SimplexCalcs.CalcEScale();
                simplex = SimplexCalcs.MirrorsEuclidean();
                Vector3D[] verts = SimplexCalcs.VertsEuclidean();
                vertex = verts[2];
            }
            else
            {
                thickness = thicknessHyperbolic;
                threshold = 0.01;

                simplex = SimplexCalcs.Mirrors(p, q, r);
                Vector3D[] verts = SimplexCalcs.VertsBall(p, q, r);
                vertex = verts[2];

                //Vector3D[] simplexVerts = SimplexCalcs.VertsBall( p, q, r );
                //H3.Cell.Edge edge = new H3.Cell.Edge( simplexVerts[2], simplexVerts[3] );
                //H3.Cell.Edge edge = SimplexCalcs.HoneycombEdgeBall( p, q, r );
                //H3.Cell.Edge[] startingEdges = new H3.Cell.Edge[] { edge };

                //H3.Cell.Edge[] edges = Recurse.CalcEdgesSmart2( simplex, startingEdges );

                // Vertex Centered.
                bool vertexCentered = false;
                if (vertexCentered)
                {
                    Vector3D v = SimplexCalcs.VertexPointBall(p, q, r);
                    v = H3Models.BallToUHS(v);
                    double scale = 1.0 / v.Abs();
                    edges = edges.Select(e =>
                    {
                        Vector3D start = H3Models.UHSToBall(H3Models.BallToUHS(e.Start) * scale);
                        Vector3D end   = H3Models.UHSToBall(H3Models.BallToUHS(e.End) * scale);
                        return(new H3.Cell.Edge(start, end));
                    }).ToArray();
                }

                // Code to show endpoints of 535

                /*using( StreamWriter sw = File.CreateText( "535_points.pov" ) )
                 * {
                 *      HashSet<Vector3D> verts = new HashSet<Vector3D>();
                 *      foreach( H3.Cell.Edge e in edges )
                 *      {
                 *              verts.Add( Sterographic.SphereToPlane( e.Start ) );
                 *              verts.Add( Sterographic.SphereToPlane( e.End ) );
                 *      }
                 *
                 *      foreach( Vector3D vert in verts )
                 *              if( !Infinity.IsInfinite( vert ) )
                 *                      sw.WriteLine( PovRay.Sphere( new Sphere() { Center = vert, Radius = 0.01 } ) );
                 * }*/
            }

            // Recurse
            bool dual = false;
            {
                H3.Cell.Edge[] startingEdges = null;
                if (dual)
                {
                    startingEdges = new H3.Cell.Edge[] { SimplexCalcs.DualEdgeBall(simplex) }
                }
                ;
                else
                {
                    //startingEdges = new H3.Cell.Edge[] { SimplexCalcs.HoneycombEdgeBall( simplex, vertex ) };
                    Vector3D[] verts  = SimplexCalcs.VertsEuclidean();
                    Vector3D   v1     = verts[0] + 2 * verts[2];             // adjacent cube center
                    Vector3D   corner = verts[3];

                    startingEdges = new H3.Cell.Edge[] { new H3.Cell.Edge(v1, corner) };
                }

                edges = Recurse.CalcEdges(simplex, startingEdges, new Recurse.Settings()
                {
                    G = g, Threshold = threshold
                });

                edges = edges.Where(e =>
                {
                    int sum = e.Depths.Count(d => d == 0);
                    return(true);
                }).ToArray();

                //CullHalfOfEdges( ref edges );

                // No need to cull edges in spherical case.
                // This was just to generate some images for 350-cell paper.
                //edges = Cull120Cell( edges );

                Simplex tet = new Simplex();
                tet.Facets = simplex;

                if (dual)
                {
                    H3.Cell.Edge[] oneDualCell = edges.Where(e => e.Depths[2] == 0).ToArray();
                    simplex = simplex.Skip(1).ToArray();
                    edges   = Recurse.CalcEdges(simplex, oneDualCell, new Recurse.Settings()
                    {
                        G = g, Threshold = threshold
                    });

                    int[]   polyMirrors  = new int[] { 0, 1, 3 };
                    H3.Cell startingCell = HoneycombGen.PolyhedronToHighlight(g, polyMirrors, tet, new Vector3D());
                    cellsToHighlight = Recurse.CalcCells(simplex, new H3.Cell[] { startingCell });
                    //cellsToHighlight = new H3.Cell[] { startingCell };
                    //cellsToHighlight = cellsToHighlight.Skip( 7 ).ToArray();
                }
                else
                {
                    int[]   polyMirrors  = new int[] { 1, 2, 3 };
                    H3.Cell startingCell = HoneycombGen.PolyhedronToHighlight(g, polyMirrors, tet, vertex);
                    //cellsToHighlight = Recurse.CalcCells( simplex, new H3.Cell[] { startingCell } );
                    cellsToHighlight = new H3.Cell[] { startingCell };
                }

                // Include just one cell?
                bool includeOne = false;
                if (includeOne)
                {
                    edges = edges.Where(e => e.Depths[0] == 0).ToArray();
                    //cellsToHighlight = cellsToHighlight.Where( c => c.Depths[0] == 0 ).ToArray();
                }
            }

            // Rotate
            bool rotate = false;

            if (rotate)
            {
                CompoundOfFive24Cells(ref edges);
            }

            // Write the file
            bool pov = true;

            if (pov)
            {
                string filename = string.Format("{0}{1}{2}.pov", p, q, r);
                PovRay.WriteEdges(new PovRay.Parameters()
                {
                    AngularThickness = thickness
                }, g, edges,
                                  filename, append: false);
                //File.Delete( filename );
                //PovRay.AppendFacets( cellsToHighlight, filename );

                HashSet <Vector3D> verts = new HashSet <Vector3D>();
                foreach (H3.Cell.Edge e in edges)
                {
                    verts.Add(e.Start);
                    verts.Add(e.End);
                }

                /*foreach( Vector3D v in verts )
                 * {
                 *      Vector3D t = v;
                 *      t.Normalize();
                 *      t *= 0.9;
                 *      System.Diagnostics.Trace.WriteLine( string.Format( "light_source {{ <{0},{1},{2}> White*.2 }}", t.X, t.Y, t.Z ) );
                 * }*/


                /*
                 * // Include the standard pov stuff, so we can batch this.
                 * string fileName = imageData.FormatFilename( string.Empty );
                 * using( StreamWriter sw = File.CreateText( fileName + ".pov" ) )
                 * {
                 *      sw.WriteLine( "#include \"C:\\Users\\hrn\\Documents\\roice\\povray\\paper\\H3.pov\"" );
                 * }
                 *
                 * bool dummy = true;	// Doesn't matter for Pov-Ray, just Shapeways meshes.
                 * H3.SaveToFile( fileName, edges, dummy, append: true );
                 */
            }
            else
            {
                if (g == Geometry.Spherical)
                {
                    edges = edges.Where(e => e.Start.Valid() && e.End.Valid() && !Infinity.IsInfinite(e.Start) && !Infinity.IsInfinite(e.End)).ToArray();
                    S3.EdgesToStl(edges);
                }
                else
                {
                    throw new System.NotImplementedException();
                }
            }
        }
Example #23
0
        private static void BatchRun(Settings config)
        {
            bool batchRun = true;

            if (!batchRun)
            {
                return;
            }

            /*HoneycombDef[] fullSet = GetFullImageSet().ToArray();
             * foreach( HoneycombDef iData in fullSet )
             * {
             *      config.Angles = new int[] { iData.P, iData.Q, iData.R };
             *      OneImage( config );
             * }*/


            //int[] ps = new int[] { 3, 4, 5, 6, 7, 8, -1 };
            //int[] qs = new int[] { 3 };
            //int[] rs = new int[] { 3, 4, 5, 6, 7, 8, -1 };

            int[] ps = new int[] { 3, 4, 5, 6, 7, 8, -1 };
            int[] qs = new int[] { 3, 4, 5, 6, 7, 8, -1 };
            int[] rs = new int[] { 3, 4, 5, 6, 7, 8, -1 };
            //int[] rs = new int[] { 8, 9, 10, 11, 12, 13, 14, 15, 20, 25, 30 };

            //int[] rs = new int[] { 3 };
            foreach (int p in ps)
            {
                foreach (int q in qs)
                {
                    foreach (int r in rs)
                    {
                        //if( !( Geometry2D.GetGeometry( p, q ) == Geometry.Hyperbolic || Geometry2D.GetGeometry( q, r ) == Geometry.Hyperbolic ) )
                        //	continue;
                        //if( !( Geometry2D.GetGeometry( p, q ) == Geometry.Spherical || Geometry2D.GetGeometry( q, r ) == Geometry.Spherical ) )
                        //continue;

                        if (!((p == 7 && q == 3 && r == 3)))
                        {
                            continue;
                        }
                        //if( !(p==3) ) continue;
                        //if( !(p ==4||p==5) ) continue;
                        //if( q!=7 ) continue;
                        //if( r!=5 ) continue;
                        //if( r!=3 ) continue;
                        //if( !(r==4 || r== 5)) continue;

                        //if( Geometry2D.GetGeometry( q, r ) != Geometry.Spherical )
                        //	continue;

                        config.Angles = new int[] { p, q, r };
                        //OneImage( config );
                        string fileName = config.FileName("pov");
                        System.Console.WriteLine(fileName);
                        if (File.Exists(fileName))
                        {
                            System.Console.WriteLine("Skipping because it exists.");
                            //continue;
                        }

                        HoneycombDef def = new HoneycombDef(p, q, r);
                        CreateCellPovRay(def, fileName);
                        config.Angles = new int[] { p, q, r };
                        //OneImage( config );
                    }
                }
            }
        }