Exemplo n.º 1
0
        public void Gen()
        {
            Vector3D[] verts = Verts(m_m, m_k);
            Sphere[]   tet   = Tetrahedron(verts);
            Quad       quad  = new Quad()
            {
                Verts = verts
            };

            // We need to avoid infinities.
            //tet = tet.Select( s => H3Models.UHSToBall( s ) ).ToArray();
            //for( int i=0; i<quad.Verts.Length; i++ )
            //	quad.Verts[i] = H3Models.UHSToBall( quad.Verts[i] );

            // Reflect it around.
            //Quad[] quads = new Quad[] { quad };
            Quad[] quads = CalcQuads(tet, quad);

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

            foreach (Quad q in quads)
            {
                q.R3toS3();
                edges.AddRange(q.GenEdges());
            }

            string filename = string.Format("lawson_{0}_{1}.pov", m_m, m_k);

            PovRay.WriteEdges(new PovRay.Parameters()
            {
                AngularThickness = 0.01
            },
                              Geometry.Spherical, edges.ToArray(), filename, append: false);
        }
Exemplo n.º 2
0
        public static void HopfOrbit()
        {
            List <Vector3D> s2Points = new List <Vector3D>();

            for (double theta = Math.PI * .1; theta <= Math.PI * .9; theta += Math.PI * .2)
            {
                for (double lon = -Math.PI; lon <= Math.PI; lon += Math.PI / 10)
                {
                    s2Points.Add(SphericalCoords.SphericalToCartesian(new Vector3D(1.0, theta, lon)));
                }
            }

            using (StreamWriter sw = File.CreateText(@".\out.pov"))
            {
                System.Func <Vector3D, Sphere> sizeFunc = v => new Sphere()
                {
                    Center = v, Radius = 0.01
                };
                foreach (Vector3D s2Point in s2Points)
                {
                    Vector3D[] circlePoints = OneHopfCircle(s2Point);

                    //for( int i = 0; i < circlePoints.Length; i++ )
                    //	circlePoints[i] = circlePoints[i].ProjectTo3DSafe( 1.0 );

                    // Note: effectively orthogonal projects here because EdgeSphereSweep doesn't write W coord.
                    string circleString = PovRay.EdgeSphereSweep(circlePoints, sizeFunc);
                    sw.WriteLine(circleString);
                }
            }
        }
Exemplo n.º 3
0
        private string StartRenderVaryRatio(string dirname)
        {
            var anchorsFilename = GetAnchorsFilename();

            Utility.CreateDirectory(dirname, Settings.Calculation.Overwrite);
            WriteAnchorsFile(dirname);
            var dataFiles = new List <string>();

            var minR = Settings.Calculation.RatioMin;
            var maxR = Settings.Calculation.RatioMax;

            for (var i = 0; i < Settings.Calculation.FrameCount; i++)
            {
                var step = i / (double)Settings.Calculation.FrameCount;

                var r = maxR * step + minR;
                Settings.Calculation.Ratio = r;
                //var file = StartRender(dirname);
                var file = WriteDataPoints(dirname);
                dataFiles.Add(file);
            }

            var povFile = PovRay.PreparePovRayFilesWithIni(Settings, dataFiles, anchorsFilename, dirname);

            Console.WriteLine("Written " + povFile);
            return(povFile);
        }
Exemplo n.º 4
0
        /// <summary>
        /// This was used during batching.
        /// </summary>
        private static void SetupBaseHue(string fileName, string mirrorsString, int baseHue)
        {
            return;

            // Setup Pov-ray stuff.
            // We have 16 possible mirror states.  We'll calculate the hue by converting the binary state to decimal, and doubling.
            // So for a given family, the hue will range over 32 numbers.
            int hue = baseHue + 2 * Convert.ToInt32(mirrorsString, 2);

            using (StreamWriter sw = File.CreateText(fileName + ".pov"))
            {
                if (baseHue == -1)
                {
                    sw.WriteLine("background { rgb 1 }");
                }
                else
                {
                    sw.WriteLine(string.Format("background {{ CHSL2RGB( <{0}, 1, .1> ) }}", hue));
                }
                if (ViewPath != null)
                {
                    sw.WriteLine(string.Format("#declare lookAt = {0};", PovRay.FormatVec(ViewPath.LookAt)));
                }

                // This needs to come last, since it relies on the lookAt.
                sw.WriteLine("#include \"D:\\roice\\povray\\H3_paracompact.pov\"");
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Hopf Link between two points on S^2.
        /// </summary>
        public static void HopfLink(StreamWriter sw, Vector3D s2_1, Vector3D s2_2, bool anti)
        {
            Vector3D[] circlePoints;
            string     circleString;

            circlePoints = OneHopfCircleProjected(s2_1, anti);
            circleString = PovRay.EdgeSphereSweep(circlePoints, SizeFunc);
            sw.WriteLine(circleString);
            circlePoints = OneHopfCircleProjected(s2_2, anti);
            circleString = PovRay.EdgeSphereSweep(circlePoints, SizeFunc);
            sw.WriteLine(circleString);

            Mesh mesh = new Mesh();

            Vector3D[] interpolated = S3.GeodesicPoints(s2_1, s2_2);
            for (int i = 0; i < interpolated.Length - 1; i++)
            {
                Vector3D   v1 = interpolated[i];
                Vector3D   v2 = interpolated[i + 1];
                Vector3D[] p1 = OneHopfCircleProjected(v1, anti);
                Vector3D[] p2 = OneHopfCircleProjected(v2, anti);

                for (int j = 0; j < p1.Length - 1; j++)
                {
                    Mesh.Triangle t1 = new Mesh.Triangle(p1[j], p1[j + 1], p2[j]);
                    Mesh.Triangle t2 = new Mesh.Triangle(p2[j], p1[j + 1], p2[j + 1]);
                    mesh.Triangles.Add(t1);
                    mesh.Triangles.Add(t2);
                }
            }

            PovRay.WriteMesh(sw, mesh, append: true);
        }
Exemplo n.º 6
0
        public static void Cell633()
        {
            TilingConfig config = new TilingConfig(6, 3, maxTiles: 20000);
            Tiling       tiling = new Tiling();

            tiling.GenerateInternal(config, Polytope.Projection.VertexCentered);

            double edgeLength = Honeycomb.EdgeLength(6, 3, 3);

            double z      = 0.25;
            double offset = H3Models.UHS.ToEHorizontal(edgeLength, z);
            double scale  = offset / tiling.Tiles.First().Boundary.Segments.First().Length;

            foreach (Tile tile in tiling.Tiles)
            {
                tile.Transform(Mobius.Scale(scale));
            }

            Vector3D dummy;
            double   radius;

            H3Models.UHS.Geodesic(new Vector3D(0, 0, z), new Vector3D(scale, 0, z), out dummy, out radius);
            Vector3D midradius = H3Models.UHSToBall(new Vector3D(0, 0, radius));
            double   temp      = midradius.Z;
            double   temp2     = (1 - temp) / 2;
            double   temp3     = temp + temp2;
            double   temp4     = temp3;

            Vector3D circumradius = H3Models.UHSToBall(new Vector3D(0, 0, z));

            temp  = circumradius.Z;
            temp2 = (1 - temp) / 2;
            temp3 = temp + temp2;
            temp4 = temp3;

            // Checking

            /*
             * Vector3D test = new Vector3D( offset, 0, z );
             * test = H3Models.UHSToBall( test );
             * double edgeLength2 = DonHatch.e2hNorm( test.Abs() );
             * edgeLength2 += 0;
             */

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

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    H3.Cell.Edge edge = new H3.Cell.Edge(
                        H3Models.UHSToBall(seg.P1 + new Vector3D(0, 0, z)),
                        H3Models.UHSToBall(seg.P2 + new Vector3D(0, 0, z)));
                    edges.Add(edge);
                }
            }

            PovRay.WriteH3Edges(new PovRay.Parameters(), edges.ToArray(), "edges.pov");
        }
Exemplo n.º 7
0
 public void GenPovRay()
 {
     //H3.Cell.Edge[] fibers = Helicoid();
     H3.Cell.Edge[] fibers = Hyperboloid();
     PovRay.WriteH3Edges(new PovRay.Parameters {
         AngularThickness = 0.015
     }, fibers, "ruled.pov");
 }
Exemplo n.º 8
0
        private void AppendMesh(List <H3.Cell.Edge> fiberList, string filename)
        {
            Mesh mesh = new Mesh();

            for (int j = 0; j < fiberList.Count - 1; j++)
            {
                AddRow(mesh, fiberList[j], fiberList[j + 1]);
            }
            //AddRow( mesh, fiberList.Last(), fiberList.First() );
            PovRay.WriteMesh(mesh, filename, append: true);
        }
Exemplo n.º 9
0
        // 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 } ) );
                }
            }
        }
Exemplo n.º 10
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));
                }
            }
        }
Exemplo n.º 11
0
        private string StartRenderWithAngle(string dirname)
        {
            Utility.CreateDirectory(dirname, Settings.Calculation.Overwrite);
            var anchorsFilename = GetAnchorsFilename();

            WriteAnchorsFile(dirname);

            var datapointFiles = VaryAngle.WriteDataPointsVaryAngle(ShapeName, Settings, AnchorPoints, dirname);

            var povFile = PovRay.PreparePovRayFilesWithIni(Settings, datapointFiles, anchorsFilename, dirname);

            return(povFile);
        }
Exemplo n.º 12
0
        public static void Hypercube()
        {
            List <Vector3D> vertices = new List <Vector3D>();

            vertices.Add(new Vector3D(1, 1, 1, 1));
            vertices.Add(new Vector3D(1, 1, 1, -1));
            vertices.Add(new Vector3D(1, 1, -1, 1));
            vertices.Add(new Vector3D(1, 1, -1, -1));
            vertices.Add(new Vector3D(1, -1, 1, 1));
            vertices.Add(new Vector3D(1, -1, 1, -1));
            vertices.Add(new Vector3D(1, -1, -1, 1));
            vertices.Add(new Vector3D(1, -1, -1, -1));
            vertices.Add(new Vector3D(-1, 1, 1, 1));
            vertices.Add(new Vector3D(-1, 1, 1, -1));
            vertices.Add(new Vector3D(-1, 1, -1, 1));
            vertices.Add(new Vector3D(-1, 1, -1, -1));
            vertices.Add(new Vector3D(-1, -1, 1, 1));
            vertices.Add(new Vector3D(-1, -1, 1, -1));
            vertices.Add(new Vector3D(-1, -1, -1, 1));
            vertices.Add(new Vector3D(-1, -1, -1, -1));

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

            foreach (Vector3D v1 in vertices)
            {
                foreach (Vector3D v2 in vertices)
                {
                    if (v1.Dist(v2) == 2)
                    {
                        edges.Add(new H3.Cell.Edge(v1, v2));
                    }
                }
            }

            // Radial project to S3, then stereographic to R3.
            foreach (H3.Cell.Edge edge in edges)
            {
                edge.Start.Normalize();
                edge.Start = Sterographic.S3toR3(edge.Start);
                edge.End.Normalize();
                edge.End = Sterographic.S3toR3(edge.End);
            }

            PovRay.WriteEdges(new PovRay.Parameters()
            {
                AngularThickness = .05
            }, Geometry.Spherical, edges.ToArray(), "433.pov", append: false);
        }
Exemplo n.º 13
0
        private string StartRenderNoRepeatNearest(string dirname)
        {
            var dataPointsFilename = Utility.GetDatapointsFilename(ShapeName, Settings);
            var anchorsFilename    = GetAnchorsFilename();

            Utility.CreateDirectory(dirname, Settings.Calculation.Overwrite);
            WriteAnchorsFile(dirname);
            NoRepeatNearest.WriteDataPointsNoRepeatAnchor(Settings, AnchorPoints, dirname, dataPointsFilename);
            var dataFiles = new List <string> {
                dataPointsFilename
            };
            var povFile = PovRay.PreparePovRayFilesWithIni(Settings, dataFiles, anchorsFilename, dirname);

            Console.WriteLine("Written " + povFile);
            return(dataPointsFilename);
        }
Exemplo n.º 14
0
        public static void ElevenCell()
        {
            Graph g = new Graph();

            g.SetupCompleteGraph(11);

            GraphRelaxation relaxer = new GraphRelaxation();

            relaxer.Graph          = g;
            relaxer.NodeRepulsion  = 0.01;
            relaxer.EdgeAttraction = 0.0;
            relaxer.EdgeRepulsion  = 0.0;
            relaxer.Relax(20000);

            Vector3D northPole = new Vector3D(0, 0, 0, 1);

            H3.Cell.Edge[] edges = g.Edges.Select(e =>
            {
                Vector3D v1 = g.Nodes[e.V1].Position.ToVec3D();
                Vector3D v2 = g.Nodes[e.V2].Position.ToVec3D();
                //if( v1.Compare( northPole, .5 ) || v2.Compare( northPole, 0.5 ) )	// Cull edges near north pole.
                //	return null;
                v1 = Sterographic.S3toR3(v1);
                v2 = Sterographic.S3toR3(v2);
                return(new H3.Cell.Edge(v1, v2));
            }).ToArray();

            edges = edges.Where(e => e != null).ToArray();

            bool povray = false;

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

                PovRay.WriteEdges(new PovRay.Parameters {
                    AngularThickness = 0.03
                }, Geometry.Spherical, edges, filename, append: true);
            }
            else
            {
                S3.EdgesToStl(edges);
            }
        }
Exemplo n.º 15
0
        public void Generate(int X, int Y, int Z)
        {
            // The starting 3 polygons, connected up at a vertex.
            Polygon[] starting = GenerateStarting(X, Y, Z);
            starting.ToList().ForEach(p => AddPoly(p));

            for (int i = 0; i < 20; i++)
            {
                OneChain();
            }

            //m_polygons = m_polygons.Skip( 55 ).Take(3).ToList();

            // Write it out so we can see it.
            File.Delete("test.pov");
            PovRay.AppendEuclideanPolygons(m_polygons.ToArray(), "test.pov");
        }
Exemplo n.º 16
0
        void WriteFibers(List <H3.Cell.Edge> fiberList, string fileName)
        {
            H3.Cell.Edge[] fibers = fiberList.Where(f => f != null).ToArray();

            if (Ball)
            {
                PovRay.WriteH3Edges(new PovRay.Parameters {
                    AngularThickness = 0.020
                }, fibers, fileName, append: true);
            }
            else
            {
                PovRay.WriteH3Edges(new PovRay.Parameters {
                    AngularThickness = 0.010, Halfspace = true
                }, fibers, fileName, append: true);
            }
        }
Exemplo n.º 17
0
        public static void Polarity()
        {
            TilingConfig config = new TilingConfig(3, 7, 50);
            Tiling       tiling = new Tiling();

            tiling.GenerateInternal(config);

            List <Vector3D>     points = new List <Vector3D>();
            List <H3.Cell.Edge> edges  = new List <H3.Cell.Edge>();

            foreach (Polygon p in tiling.Tiles.Select(t => t.Boundary))
            {
                foreach (Segment s in p.Segments)
                {
                    foreach (Vector3D v in s.Subdivide(25))
                    {
                        Vector3D     klein = HyperbolicModels.PoincareToKlein(v);
                        H3.Cell.Edge e     = Dual(klein);
                        points.Add(klein);
                        edges.Add(e);
                    }
                }
            }

            using (StreamWriter sw = File.CreateText("polarity.pov"))
            {
                double rad = 0.01;
                foreach (Vector3D vert in points)
                {
                    sw.WriteLine(PovRay.Sphere(new Sphere()
                    {
                        Center = vert, Radius = rad
                    }));
                }
                foreach (H3.Cell.Edge edge in edges)
                {
                    sw.WriteLine(PovRay.Cylinder(edge.Start, edge.End, rad / 2));
                }
            }
        }
Exemplo n.º 18
0
        public static void RLD_Surface()
        {
            RLD_outputs outputs;
            Mesh        mesh = new Mesh();

            SurfaceInternal(out outputs);
            double scale = m_params.Scale;

            // Now add in all the catenoids.
            double mInc = Math.PI * 2 / m_params.M;

            for (int k = 1; k < outputs.x_i.Length; k++)
            {
                for (int m = 0; m < m_params.M; m++)
                {
                    Vector3D loc = SphericalCoords.SphericalToCartesian(new Vector3D(1, Math.PI / 2 - outputs.x_i[k], m * mInc));
                    mesh.Append(Catenoid(scale, loc, outputs.phi_i[k], outputs.t_i[k]));
                }
            }

            PovRay.WriteMesh(mesh, "RLD.pov");
        }
Exemplo n.º 19
0
        public static void PovRayModel()
        {
            Vector3D cen = HoneycombPaper.InteriorPointBall;

            cen = H3Models.BallToUHS(cen);
            Sphere[] simplex = Simplex(ref cen);

            H3.Cell[] simplicesFinal = GenTruss(simplex, null, cen, ball: true);
            string    fileName       = "350cell.pov";

            System.IO.File.Delete(fileName);
            foreach (H3.Cell cell in simplicesFinal)
            {
                //int[] include = new int[] { 0, 1, 2, 3 };
                int[] include = new int[] { 0 };
                PovRay.AppendSimplex(cell.Facets.Select(f => f.Sphere).ToArray(), cell.Center, include, fileName);
            }

            /*
             * HashSet<H3.Cell.Edge> axes = new HashSet<H3.Cell.Edge>( new H3.Cell.EdgeEqualityComparer() );
             * H3.Cell.Edge axis = new H3.Cell.Edge( new Vector3D( 0, 0, -1 ), new Vector3D( 0, 0, 1 ) );
             * axes.Add( axis );
             * foreach( int[] reflections in TrussReflections() )
             * {
             *      Vector3D s = axis.Start, e = axis.End;
             *      foreach( int ri in reflections )
             *      {
             *              s = simplex[ri].ReflectPoint( s );
             *              e = simplex[ri].ReflectPoint( e );
             *      }
             *      axes.Add( new H3.Cell.Edge( s, e ) );
             * }
             * PovRay.WriteH3Edges( new PovRay.Parameters { AngularThickness = 0.045 }, axes.ToArray(), "axes.pov" );
             *
             * H3.Cell.Edge[] fibers = new H3.Cell.Edge[] { axis };
             * fibers = Recurse.CalcEdges( simplex.Skip(1).ToArray(), fibers );
             * PovRay.WriteH3Edges( new PovRay.Parameters { AngularThickness = 0.025 }, fibers, "axes.pov" );*/
        }
Exemplo n.º 20
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);
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// This is like the GenCell method, but super hacked up for the Catacombs image with Henry.
        /// </summary>
        internal static void GenCellCatacombs(Sphere[] simplex, bool ball)
        {
            // We don't want to include the first mirror (which reflects across cells).
            Sphere[] mirrors    = simplex.Skip(1).ToArray();
            Sphere[] allMirrors = simplex.ToArray();

            // Simplices will be the "cells" in Recurse.CalcCells.
            H3.Cell.Facet[] simplexFacets = simplex.Select(m => new H3.Cell.Facet(m)).ToArray();

            // Offset cell boundary ever so slightly, to avoid artifacts of adjacent cells.
            Sphere toReflectLater = simplexFacets[0].Sphere.Clone();

            //simplexFacets[0].Sphere = CoxeterImages.GeodesicOffset( simplexFacets[0].Sphere, ball ? -1e-6 : 1e-7, ball );

            H3.Cell startingCell = new H3.Cell(simplexFacets);
            startingCell = startingCell.Clone();                // So our mirrors don't get munged after we reflect around later.
            Vector3D cen = new Vector3D(0.05, 0.01, -0.05);     //	373, 438

            //Vector3D cen = new Vector3D( 0.05, 0.01, 100 );		//	637
            //cen.RotateXY( Math.PI / 2 );	// only if we also rotate simplex mirrors.  XXX - make a setting.
            startingCell.Center = cen;
            H3.Cell[] simplices = Recurse.CalcCells(mirrors, new H3.Cell[] { startingCell }, new Recurse.Settings()
            {
                Ball = ball
            });

            List <H3.Cell> simplicesFinal = new List <H3.Cell>();
            List <int[]>   reflectionSets = new List <int[]>();

            // 1 reflects in x-axis
            // 3, 1 rotates right
            // 1, 3 rotates left

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

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

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

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

            //reflectionSets.Add( new int[] { 0, 3, 1, 3, 1, 0, 2, 3, 1 } );
            //reflectionSets.Add( new int[] { 0, 3, 1, 3, 1, 0, 3, 1, 3, 1, 3, 1, 2, 3, 1, 3, 1, 0, 1, 3 } );	// baby
            //reflectionSets.Add( new int[] { 0, 3, 1, 3, 1, 0, 3, 1, 3, 1, 3, 1, 2 } );	// maybe
            //reflectionSets.Add( new int[] { 0, 3, 1, 2, 3, 1, 0, 2, 1, 3 } );
            //reflectionSets.Add( new int[] { 0, 3, 1, 2, 3, 1, 0, 3, 1, 2 } );		// not great orientation
            // reflectionSets.Add( new int[] { 0, 3, 1, 3, 1, 2 } );	// big

            bool ceiling = true;

            if (ceiling)
            {
                simplicesFinal = simplices.ToList();
            }
            else
            {
                foreach (int[] set in reflectionSets)
                {
                    List <H3.Cell> copy = simplices.Select(s => s.Clone()).ToList();
                    foreach (int r in set)
                    {
                        foreach (H3.Cell cell in copy)
                        {
                            cell.Reflect(allMirrors[r]);
                        }
                    }
                    simplicesFinal.AddRange(copy);
                }
            }

            /*
             * // A second cell.
             * //toReflectLater = simplices[45].Facets[0].Sphere.Clone();
             * //toReflectLater = simplices.First( s => s.Depth == 2 ).Facets[0].Sphere.Clone();
             * foreach( H3.Cell cell in simplices )
             *      cell.Reflect( toReflectLater );
             *
             * // A third cell.
             * toReflectLater = simplices[40].Facets[0].Sphere.Clone();
             * //toReflectLater = simplices.First( s => s.Depth == 4 ).Facets[0].Sphere.Clone();
             * foreach( H3.Cell cell in simplices )
             *      cell.Reflect( toReflectLater );
             *
             * foreach( H3.Cell cell in simplices )
             *      cell.Depths = new int[4];
             * List<H3.Cell> simplicesFinal = Recurse.CalcCells2( mirrors, simplices ).ToList();
             * simplicesFinal = simplicesFinal.Where( s => s.Depths[0] % 3 == 1 && s.Depths[1] % 2 == 0 && s.Depths[2] % 2 == 1 ).ToList();
             */

            /*
             * List<H3.Cell> simplicesFinal = new List<H3.Cell>();
             * //for( int d = 0; d < 1; d+=2 )
             * int d = 0;
             * {
             *      //Sphere toReflect = simplices.First( s => s.Depth == d ).Facets[0].Sphere.Clone();
             *      //Sphere toReflect = simplices.Where( s => s.Depth == d ).Skip(1).Take(1).First().Facets[0].Sphere.Clone();
             *      List<H3.Cell> reflectionCells = simplices.Where( s => s.Depths[1] == d && s.Depths[0] % 2 == 0 ).Skip(0).Take(1).ToList();
             *      foreach( Sphere toReflect in reflectionCells.Select( c => c.Facets[0].Sphere.Clone() ) )
             *      {
             *              List<H3.Cell> thisCell = new List<H3.Cell>();
             *              foreach( H3.Cell cell in simplices )
             *              {
             *                      H3.Cell clone = cell.Clone();
             *                      clone.Reflect( toReflect );
             *                      thisCell.Add( clone );
             *              }
             *
             *              //Sphere toReflect2 = thisCell.First( s => s.Depth1 == d + 3 && s.Depth0 % 2 == 0 ).Facets[0].Sphere.Clone();
             *              //List<H3.Cell> reflectionCellsTemp = simplices.Where( s => Math.Abs( s.Depths[1] - d ) == 2 && s.Depths[0] % 2 == 0 ).ToList();
             *              List<H3.Cell> reflectionCellsTemp = simplices.Where( s => s.Depths[1] == 2 && s.Depths[1] == s.Depths[0] + s.Depths[2] ).ToList();
             *              List<H3.Cell> reflectionCells2 = reflectionCellsTemp;//.Where( ( x, i ) => i % 3 == 0 ).ToList(); // .Skip( 5 ).Take( 5 ).ToList();
             *              foreach( Sphere toReflect2 in reflectionCells2.Select( c => c.Facets[0].Sphere.Clone() ) )
             *              //Sphere toReflect2 = toReflectLater;
             *              {
             *                      foreach( H3.Cell cell in thisCell )
             *                      {
             *                              H3.Cell clone = cell.Clone();
             *                              clone.Reflect( toReflect2 );
             *                              simplicesFinal.Add( clone );
             *                      }
             *              }
             *      }
             * }*/

            int count = 0;

            foreach (H3.Cell cell in simplicesFinal)
            {
                count++;

                //if( count % 2 == 0 )
                //	continue;

                /*if( count < 1 )
                 *      continue;
                 * if( count > 30 )
                 *      return;
                 */
                //int[] include = new int[] { 0, 1, 2, 3 };
                int[] include = new int[] { 0 };
                PovRay.AppendSimplex(cell.Facets.Select(f => f.Sphere).ToArray(), cell.Center, include, "cell.pov");
            }
        }
Exemplo n.º 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();
                }
            }
        }
Exemplo n.º 23
0
        /// <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);
            }
        }
Exemplo n.º 24
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);
            }
        }
Exemplo n.º 25
0
 public static void ToPovRay(Sphere[] mirrors)
 {
     System.IO.File.Delete("simplex.pov");
     PovRay.CreateSimplex(mirrors, "simplex.pov");
 }
Exemplo n.º 26
0
        public void Gen(int p, int q, int r)
        {
            Geometry g = Util.GetGeometry(p, q, r);

            if (g != Geometry.Spherical)
            {
                throw new System.Exception("Point group code only for spherical geometry.");
            }

            Simplex simplex = new Simplex();

            simplex.Facets = SimplexCalcs.Mirrors(p, q, r);
            Vector3D cen        = new Vector3D();
            Vector3D faceCenter = SimplexCalcs.FaceCenterSpherical(p, q, r);
            Vector3D edgeMid    = SimplexCalcs.EdgeMidpointSpherical(p, q, r);
            Vector3D vertex     = SimplexCalcs.VertexSpherical(p, q, r);

            List <Vector3D> startingPoles = new List <Vector3D>();

            startingPoles.Add(Sterographic.S3toR3(GreatSphere.FromSphere(simplex.Facets[0]).Pole));
            GreatSphere[] spheres = CalcSpheres(simplex.Facets, startingPoles.ToArray());

            string filename = "point_group.pov";

            using (StreamWriter sw = File.CreateText(filename))
            {
                //foreach( var greatSphere in spheres )
                //sw.WriteLine( PovRay.Sphere( greatSphere.ToSphere() ) );
            }

            /*
             * List<H3.Cell.Edge> startingEdges = new List<H3.Cell.Edge>();
             * startingEdges.Add( new H3.Cell.Edge( cen, faceCenter ) );
             * H3.Cell.Edge[] edges = Recurse.CalcEdges( simplex.Facets, startingEdges.ToArray(), new Recurse.Settings() { G = Geometry.Spherical, Threshold = 0.001 } );
             * //edges = edges.Where( e => !( Infinity.IsInfinite( e.Start ) || Infinity.IsInfinite( e.End ) ) ).ToArray();
             *
             * PovRay.WriteEdges( new PovRay.Parameters() { AngularThickness = 0.01 }, Geometry.Spherical, edges, filename, append: true );
             */

            double minRad = 0;
            double thick  = 0.005;

            System.Func <Vector3D, Sphere> sizeFunc = v =>
            {
                Vector3D c;
                double   rad;
                H3Models.Ball.DupinCyclideSphere(v, thick / 2, g, out c, out rad);
                return(new Sphere()
                {
                    Center = c, Radius = Math.Max(rad, minRad)
                });
            };

            // All geodesics
            List <Circle3D> startingCircles = new List <Circle3D>();

            startingCircles.Add(GeodesicFrom2Points(cen, edgeMid));
            Circle3D[] geodesics = CalcGeodesics(simplex.Facets, startingCircles.ToArray());

            Vector3D color = new Vector3D(0, 0, 1);

            using (StreamWriter sw = File.CreateText(filename))
            {
                Shapeways shapeways = new Shapeways();
                foreach (Circle3D geodesic in geodesics)
                {
                    Vector3D[] points;
                    if (Infinity.IsInfinite(geodesic.Radius))
                    {
                        double  cutoff = 15;
                        Segment seg    = Segment.Line(geodesic.Normal * cutoff, geodesic.Normal * -cutoff);
                        points = seg.Subdivide(42);
                    }
                    else
                    {
                        List <Vector3D> tempPoints = geodesic.Subdivide(150).ToList();
                        tempPoints.Add(tempPoints[0]);
                        tempPoints.Add(tempPoints[1]);
                        points = tempPoints.ToArray();
                    }

                    List <Vector3D> ePoints = new List <Vector3D>();
                    List <double>   eRadii  = new List <double>();
                    foreach (Vector3D pNE in points)
                    {
                        Sphere sphere = sizeFunc(pNE);
                        ePoints.Add(sphere.Center);
                        eRadii.Add(sphere.Radius);
                    }
                    shapeways.AddCurve(ePoints.ToArray(), eRadii.ToArray());

                    sw.WriteLine(PovRay.EdgeSphereSweep(points, sizeFunc, color));
                }

                STL.SaveMeshToSTL(shapeways.Mesh, "533.stl");
            }
        }
Exemplo n.º 27
0
        public static void CatenoidBasedSurface()
        {
            RLD_outputs outputs;

            SurfaceInternal(out outputs);
            double scale = m_params.Scale;

            // Map a point for a given k/m from the hemihypersphere to the complex plane.
            // You can also pass in -1 for k to get a point on the equator of the hemihypersphere.
            double mInc = Math.PI * 2 / m_params.M;
            Func <RLD_outputs, int, int, Vector3D> onPlane = (o, k, m) =>
            {
                double theta = k == -1 ? 0 : outputs.x_i[k];
                theta += Math.PI / 2;
                return
                    (Sterographic.SphereToPlane(
                         SphericalCoords.SphericalToCartesian(
                             new Vector3D(1, theta, m * mInc)
                             )
                         ));
            };

            // Setup texture coords on fundamental triangle.
            // We'll use a fundamental triangle in the southern hemisphere,
            // with stereographically projected coords at (0,0), (1,0), and CCW on the unit circle depending on M.
            Polygon p = new Polygon();

            p.Segments.Add(Segment.Line(new Vector3D(), new Vector3D(1, 0)));
            p.Segments.Add(Segment.Arc(new Vector3D(1, 0), onPlane(outputs, 1, 1), onPlane(outputs, -1, 1)));
            p.Segments.Add(Segment.Line(onPlane(outputs, -1, 1), new Vector3D()));
            int levels = 9;

            TextureHelper.SetLevels(levels);
            Vector3D[] coords         = TextureHelper.TextureCoords(p, Geometry.Spherical, doGeodesicDome: true);
            int[]      elementIndices = TextureHelper.TextureElements(1, levels);

            // Setup a nearTree for the catenoid locations (on the plane).
            NearTree nearTree = new NearTree(Metric.Spherical);

            for (int k = 1; k < outputs.x_i.Length; k++)
            {
                for (int m = 0; m <= 1; m++)
                {
                    Vector3D loc = onPlane(outputs, k, m);
                    nearTree.InsertObject(new NearTreeObject()
                    {
                        ID = k, Location = loc
                    });
                }
            }

            // Given a point on the plane, find the nearest catenoid center and calculate the height of the surface based on that.
            // This also calculates the locking of the point.
            Func <Vector3D, Tuple <double, Vector3D, Vector3D> > heightAndLocking = coord =>
            {
                NearTreeObject closest;
                if (!nearTree.FindNearestNeighbor(out closest, coord, double.MaxValue))
                {
                    throw new System.Exception();
                }

                Vector3D locked = new Vector3D();
                if (p.Segments[0].IsPointOn(coord) ||
                    p.Segments[2].IsPointOn(coord))
                {
                    locked = new Vector3D(1, 1, 0, 0);
                }
                //if( p.Segments[1].IsPointOn( v ) )		// Not working right for some reason, but line below will work.
                if (Tolerance.Equal(coord.Abs(), 1))
                {
                    locked = new Vector3D(1, 1, 1, 0);
                }

                Vector3D vSphere = Sterographic.PlaneToSphere(coord);
                Vector3D cSphere = Sterographic.PlaneToSphere(closest.Location);
                double   dist    = vSphere.AngleTo(cSphere);

                int    k          = (int)closest.ID;
                double waist      = outputs.t_i[k];
                double rld_height = outputs.phi_i[k];

                double h      = waist * 3.5 * 2;                                        // height where catenoid will meet rld_height.
                double factor = scale * rld_height * 2 / h;                             // Artifical scaling so we can see things.
                dist /= factor;

                double z = double.NaN;
                if (dist >= waist)
                {
                    z = waist * DonHatch.acosh(dist / waist);
                }
                else if (dist >= 0.7 * waist)
                {
                    z = 0;

                    // Move the coord to the thinnest waist circle.
                    Mobius m = new Mobius();
                    m.Hyperbolic(Geometry.Spherical, coord.ToComplex(), waist / dist);
                    coord = m.Apply(coord);
                }

                if (dist < waist * 20)
                {
                    locked = new Vector3D(1, 1, 1, 1);
                }

                return(new Tuple <double, Vector3D, Vector3D>(z * factor, locked, coord));
            };

            // Calculate all the coordinates.
            Vector3D[] locks = new Vector3D[coords.Length];
            for (int i = 0; i < coords.Length; i++)
            {
                Vector3D coord = coords[i];
                var      hl    = heightAndLocking(coord);
                locks[i]  = hl.Item2;
                coord     = hl.Item3;
                coords[i] = Normal(Sterographic.PlaneToSphere(coord), (double)hl.Item1);
            }

            // Relax it.
            Relax(coords, elementIndices, locks);

            Mesh   mesh = new Mesh();
            Sphere s    = new Sphere();

            for (int i = 0; i < elementIndices.Length; i += 3)
            {
                Vector3D a = coords[elementIndices[i]];
                Vector3D b = coords[elementIndices[i + 1]];
                Vector3D c = coords[elementIndices[i + 2]];
                if (a.DNE || b.DNE || c.DNE)
                {
                    continue;
                }

                for (int m = 0; m <= 0; m++)
                {
                    mesh.Triangles.Add(new Mesh.Triangle(a, b, c));
                    mesh.Triangles.Add(new Mesh.Triangle(
                                           s.ReflectPoint(a),
                                           s.ReflectPoint(b),
                                           s.ReflectPoint(c)));
                    a.RotateXY(mInc);
                    b.RotateXY(mInc);
                    c.RotateXY(mInc);
                }
            }

            PovRay.WriteMesh(mesh, "RLD.pov");
        }