コード例 #1
0
        private static List <Vector3D[]> BasePointsTiling()
        {
            TilingConfig config = new TilingConfig(3, 7, maxTiles: 100);
            Tiling       tiling = new Tiling();

            tiling.Generate(config);

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

            int numPerSeg = 25;
            List <Vector3D[]> basePoints = new List <Vector3D[]>();

            foreach (Tile t in tiling.Tiles)
            {
                foreach (Segment s in t.Boundary.Segments)
                {
                    H3.Cell.Edge e = new H3.Cell.Edge(s.P1, s.P2);
                    if (finished.Contains(e))
                    {
                        continue;
                    }
                    finished.Add(e);

                    Vector3D[] points = s.Subdivide(numPerSeg).Select(p =>
                    {
                        p = new Vector3D(p.X, 0, p.Y);
                        return(H3Models.BallToUHS(p));
                    }).ToArray();
                    basePoints.Add(points);
                }
            }

            return(basePoints);
        }
コード例 #2
0
        /// <summary>
        /// Generate a catenoid, then move it to a point on the hemisphere in S^3.
        /// </summary>
        private static Mesh Catenoid(double scale, Vector3D loc, double rld_height, double waist)
        {
            double h = waist * 3.5;
            //Mesh mesh = StandardCatenoid( waist, h );
            Mesh mesh = CatenoidSquared(waist, h);

            mesh.Scale(scale * rld_height * 2 / h);                     // To make the catenoid meet up with the RLD solution.

            // First move to north pole, then rotate down to the location.
            Func <Vector3D, Vector3D> transform = v =>
            {
                v = H3Models.BallToUHS(v);
                Vector3D northPole = new Vector3D(0, 0, 1);
                Vector3D axis      = loc.Cross(northPole);
                if (!axis.Normalize())  // North or south pole?
                {
                    return(v);
                }
                double anglXY = Euclidean2D.AngleToCounterClock(new Vector3D(1, 0), new Vector3D(loc.X, loc.Y));
                v.RotateXY(anglXY);
                double angleDown = loc.AngleTo(northPole);
                v.RotateAboutAxis(axis, angleDown);

                if (v.DNE || Infinity.IsInfinite(v))
                {
                    throw new System.Exception();
                }
                return(v);
            };

            mesh.Transform(transform);
            return(mesh);
        }
コード例 #3
0
        private Vector3D ApplyTransformationToSphere(Vector3D v, double t)
        {
            v = H3Models.BallToUHS(v);

            // 437 (hyperbolic)
            //v *= Math.Pow( 4.259171776329806, t*10-5 );

            // 36i (parabolic)
            //v += new Vector3D( Math.Cos( Math.PI / 6 ), Math.Sin( Math.PI / 6 ) ) * t;

            // iii (loxodromic)
            //Complex c = v.ToComplex();
            //double x = Math.Sqrt( 2 ) - 1;
            //Mobius m = new Mobius( new Complex( x, 0 ), Complex.One, new Complex( -x, 0 ) );

            // 12,12,12 loxodromic
            //m = new Mobius( new Complex( 0, 1 ), Complex.One, new Complex( 0, -1 ) );

            /*
             * c = m.Apply( c );
             * c *= Complex.Exp( new Complex( 2.5, 4 * Math.PI ) * t );
             * c = m.Inverse().Apply( c );
             * v = Vector3D.FromComplex( c );
             */

            // Center cell head in KolorEyes.
            Mobius m = new Mobius();

            m.UpperHalfPlane();
            v = m.Inverse().Apply(v);

            return(H3Models.UHSToBall(v));
        }
コード例 #4
0
        private static H3.Cell.Edge CalcFiber(Vector3D boundaryPointBall)
        {
            bool parallel = false;

            if (parallel)
            {
                Vector3D v2 = new Vector3D(0, 0, -1);                   // Really we can pick any boundary point.
                return(new H3.Cell.Edge(boundaryPointBall, v2));
            }
            else
            {
                // If the point is above the real line, it will have been connected to z.
                // If below the real line, it will have been connected to -i
                // If on the real line, it's degenerate.
                Vector3D pUHS = H3Models.BallToUHS(boundaryPointBall);
                if (Tolerance.Equal(pUHS.Y, 0))
                {
                    return(null);
                }

                Vector3D z      = Vector3D.FromComplex(ZParam);
                Vector3D minusi = new Vector3D(0, -1);

                double dilation    = double.NaN;
                double translation = double.NaN;
                if (pUHS.Y > 0)
                {
                    dilation    = pUHS.Y / z.Y;
                    z          *= dilation;
                    translation = pUHS.X - z.X;
                    z.X        += translation;
                    if (H3Models.UHSToBall(z) != boundaryPointBall)
                    {
                        throw new System.Exception();
                    }

                    minusi   *= dilation;
                    minusi.X += translation;
                    return(new H3.Cell.Edge(H3Models.UHSToBall(minusi), boundaryPointBall));
                    //return null;
                }
                else
                {
                    dilation    = pUHS.Y / -1;
                    minusi     *= dilation;
                    translation = pUHS.X - minusi.X;
                    minusi.X   += translation;
                    if (H3Models.UHSToBall(minusi) != boundaryPointBall)
                    {
                        throw new System.Exception();
                    }

                    z   *= dilation;
                    z.X += translation;
                    return(new H3.Cell.Edge(boundaryPointBall, H3Models.UHSToBall(z)));
                    //return null;
                }
            }
        }
コード例 #5
0
        private void DrawMirrors(Bitmap image, Settings settings)
        {
            double     b = settings.Bounds;
            ImageSpace i = new ImageSpace(settings.Width, settings.Height);

            i.XMin = -b; i.XMax = b;
            i.YMin = -b; i.YMax = b;

            float scale = 2;

            List <Sphere> toDraw = new List <Sphere>();

            toDraw.AddRange(settings.Mirrors);
            //toDraw.Add( AlteredFacetForTrueApparent2DTilings( settings.Mirrors ) );

            using (Graphics g = Graphics.FromImage(image))
                using (Pen p = new Pen(Color.Red, scale * 3.0f))
                    //using( Pen p2 = new Pen( Color.FromArgb( 255, 255, 214, 0 ), 3.0f ) )
                    using (Pen p2 = new Pen(Color.Orange, scale * 3.0f))
                        using (Pen p3 = new Pen(Color.Orange, scale * 3.0f))
                            for (int m = 0; m < toDraw.Count; m++)
                            {
                                Sphere s = toDraw[m];
                                Circle c = H3Models.UHS.IdealCircle(s);         // XXX - not correct
                                if (c.IsLine)
                                {
                                    DrawUtils.DrawLine(-c.P2 * 25, c.P2 * 25, g, i, p);         // XXX - not general.
                                }
                                else
                                {
                                    Sphere temp = H3Models.BallToUHS(s);
                                    DrawUtils.DrawCircle(new Circle {
                                        Center = temp.Center, Radius = temp.Radius
                                    }, g, i, m == 0 ? p2 : m == 4 ? p3 : p);
                                }

                                /* // iii
                                 * Circle c = new Circle();
                                 * c.Radius = Math.Sqrt( 2 );
                                 * c.Center = new Vector3D( 1, Math.Sqrt( 2 ) );
                                 * DrawUtils.DrawCircle( c, g, i, p );
                                 * c.Center = new Vector3D( -1, Math.Sqrt( 2 ) );
                                 * DrawUtils.DrawCircle( c, g, i, p );
                                 * c.Center = new Vector3D( Math.Sqrt( 2 ) - 1, 0 );
                                 * c.Radius = 2 - Math.Sqrt( 2 );
                                 * DrawUtils.DrawCircle( c, g, i, p );
                                 *
                                 * DrawUtils.DrawLine( new Vector3D( -2, 0 ), new Vector3D( 2, 0 ), g, i, p );
                                 */
                            }
        }
コード例 #6
0
        internal static void CalcSelfSimilarityScale()
        {
            double   inRadius   = DonHatch.h2eNorm(Honeycomb.InRadius(4, 3, 7));
            Vector3D facePoint  = new Vector3D(0, 0, -inRadius);
            Sphere   s          = H3Models.Ball.OrthogonalSphereInterior(facePoint);
            Vector3D facePoint2 = new Vector3D(0, 0, inRadius);

            facePoint2 = s.ReflectPoint(facePoint2);

            facePoint  = H3Models.BallToUHS(facePoint);
            facePoint2 = H3Models.BallToUHS(facePoint2);

            double scale = facePoint.Z / facePoint2.Z;

            scale += 0;
        }
コード例 #7
0
        public static void GenImage2()
        {
            int        size   = 10000;
            Bitmap     image  = new Bitmap(size, size);
            ImageSpace iSpace = new ImageSpace(size, size);
            double     b      = 1.0;

            iSpace.XMin = 0;
            iSpace.XMax = b;
            iSpace.YMin = 0;
            iSpace.YMax = b;

            Vector3D cen = HoneycombPaper.InteriorPointBall;

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

            Sphere inSphere = InSphere(simplex);

            using (Graphics g = Graphics.FromImage(image))
            {
                g.Clear(Color.White);

                int    count  = 75;
                double offset = b / count / 2;
                for (int i = 0; i < count; i++)
                {
                    for (int j = 0; j < count; j++)
                    {
                        Vector3D center = new Vector3D(2 * offset * i, 2 * offset * j);
                        Circle   circ   = new Circle {
                            Center = center, Radius = offset * .85
                        };

                        using (Brush brush = new SolidBrush(Color.DarkBlue))
                            DrawUtils.DrawFilledCircle(circ, g, iSpace, brush);
                    }
                }
            }

            image.Save("fundamental.png", ImageFormat.Png);
        }
コード例 #8
0
        public static void GenImage()
        {
            int        size  = 1000;
            Bitmap     image = new Bitmap(size, size);
            ImageSpace i     = new ImageSpace(size, size);
            double     b     = 1.1;

            i.XMin = -b; i.XMax = b;
            i.YMin = -b; i.YMax = b;

            Vector3D cen = HoneycombPaper.InteriorPointBall;

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

            Sphere inSphere = InSphere(simplex);

            using (Graphics g = Graphics.FromImage(image))
                foreach (int[] reflections in AllCells())
                {
                    Sphere clone = inSphere.Clone();
                    foreach (int r in reflections)
                    {
                        clone.Reflect(simplex[r]);
                    }


                    Sphere   ball = new Sphere();
                    Circle3D inSphereIdealBall = ball.Intersection(clone);
                    Circle3D inSphereIdealUHS  = H3Models.BallToUHS(inSphereIdealBall);
                    Circle   inSphereIdeal     = new Circle {
                        Center = inSphereIdealUHS.Center, Radius = inSphereIdealUHS.Radius
                    };

                    using (Brush brush = new SolidBrush(Color.Blue))
                        DrawUtils.DrawFilledCircle(inSphereIdeal, g, i, brush);
                }

            image.Save("threefifty.png", ImageFormat.Png);
        }
コード例 #9
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" );*/
        }
コード例 #10
0
        /// <summary>
        /// Returns the 6 simplex edges in the UHS model.
        /// </summary>
        public static H3.Cell.Edge[] SimplexEdgesUHS(int p, int q, int r)
        {
            // Only implemented for honeycombs with hyperideal cells right now.
            if (!(Geometry2D.GetGeometry(p, q) == Geometry.Hyperbolic))
            {
                throw new System.NotImplementedException();
            }

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

            Circle[] circles = simplex.Select(s => H3Models.UHS.IdealCircle(s)).ToArray();

            Vector3D[] defPoints = new Vector3D[6];
            Vector3D   dummy;

            Euclidean2D.IntersectionLineCircle(circles[1].P1, circles[1].P2, circles[0], out defPoints[0], out dummy);
            Euclidean2D.IntersectionLineCircle(circles[2].P1, circles[2].P2, circles[0], out defPoints[1], out dummy);
            Euclidean2D.IntersectionLineCircle(circles[1].P1, circles[1].P2, circles[3], out defPoints[2], out dummy);
            Euclidean2D.IntersectionLineCircle(circles[2].P1, circles[2].P2, circles[3], out defPoints[3], out dummy);

            Circle3D c = simplex[0].Intersection(simplex[3]);

            Vector3D normal = c.Normal;

            normal.RotateXY(Math.PI / 2);
            Vector3D intersection;
            double   height, off;

            Euclidean2D.IntersectionLineLine(c.Center, c.Center + normal, circles[1].P1, circles[1].P2, out intersection);
            off            = (intersection - c.Center).Abs();
            height         = Math.Sqrt(c.Radius * c.Radius - off * off);
            intersection.Z = height;
            defPoints[4]   = intersection;

            Euclidean2D.IntersectionLineLine(c.Center, c.Center + normal, circles[2].P1, circles[2].P2, out intersection);
            off            = (intersection - c.Center).Abs();
            height         = Math.Sqrt(c.Radius * c.Radius - off * off);
            intersection.Z = height;
            defPoints[5]   = intersection;

            // Hyperideal vertex too?
            bool order = false;

            H3.Cell.Edge[] edges = null;
            if (Geometry2D.GetGeometry(q, r) == Geometry.Hyperbolic)
            {
                edges = new H3.Cell.Edge[]
                {
                    new H3.Cell.Edge(new Vector3D(), new Vector3D(0, 0, 10)),
                    new H3.Cell.Edge(defPoints[4], defPoints[5], order),
                    new H3.Cell.Edge(defPoints[0], defPoints[4], order),
                    new H3.Cell.Edge(defPoints[1], defPoints[5], order),
                    new H3.Cell.Edge(defPoints[2], defPoints[4], order),
                    new H3.Cell.Edge(defPoints[3], defPoints[5], order),
                };
            }
            else
            {
                Vector3D vPointUHS = H3Models.BallToUHS(VertexPointBall(p, q, r));
                defPoints[0] = defPoints[1] = vPointUHS;
                edges        = new H3.Cell.Edge[]
                {
                    new H3.Cell.Edge(vPointUHS, new Vector3D(0, 0, 10)),
                    new H3.Cell.Edge(defPoints[4], defPoints[5], order),
                    new H3.Cell.Edge(defPoints[0], defPoints[4], order),
                    new H3.Cell.Edge(defPoints[1], defPoints[5], order),
                    new H3.Cell.Edge(defPoints[2], defPoints[4], order),
                    new H3.Cell.Edge(defPoints[3], defPoints[5], order),
                };
            }

            return(edges);
        }
コード例 #11
0
        /// <summary>
        /// This will return an altered facet to create true apparent 2D tilings (proper bananas) on the boundary.
        /// Notes:
        ///		The input simplex must be in the ball model.
        ///		The first mirror of the simplex (the one that mirrors across cells) is the one we end up altering.
        /// </summary>
        public static Sphere AlteredFacetForTrueApparent2DTilings(Sphere[] simplex)
        {
            //Sphere m = H3Models.BallToUHS( simplex[0] );
            //Sphere t = new Sphere() { Center = m.Center, Radius = m.Radius*100 };
            //return H3Models.UHSToBall( t );

            // We first need to find the size of the apparent 2D disk surrounding the leg.
            // This is also the size of the apparent cell head disk of the dual.
            // So we want to get the midsphere (insphere would also work) of the dual cell with that head,
            // then calculate the intersection of that with the boundary.
            Sphere cellMirror = simplex[0];

            if (cellMirror.IsPlane)
            {
                throw new System.NotImplementedException();
            }

            // The point centered on a face is the closest point of the cell mirror to the origin.
            // This will be the point centered on an edge on the dual cell.
            Vector3D facePoint = cellMirror.ProjectToSurface(new Vector3D());

            // Reflect it to get 3 more points on our midsphere.
            Vector3D reflected1 = simplex[1].ReflectPoint(facePoint);
            Vector3D reflected2 = simplex[2].ReflectPoint(reflected1);
            Vector3D reflected3 = simplex[0].ReflectPoint(reflected2);
            Sphere   midSphere  = Sphere.From4Points(facePoint, reflected1, reflected2, reflected3);

            // Get the ideal circles of the cell mirror and midsphere.
            // Note: The midsphere is not geodesic, so we can't calculate it the same.
            Sphere cellMirrorUHS   = H3Models.BallToUHS(cellMirror);
            Circle cellMirrorIdeal = H3Models.UHS.IdealCircle(cellMirrorUHS);

            Sphere   ball = new Sphere();
            Circle3D midSphereIdealBall = ball.Intersection(midSphere);               // This should exist because we've filtered for honeycombs with hyperideal verts.
            Circle3D midSphereIdealUHS  = H3Models.BallToUHS(midSphereIdealBall);
            Circle   midSphereIdeal     = new Circle {
                Center = midSphereIdealUHS.Center, Radius = midSphereIdealUHS.Radius
            };

            // The intersection point of our cell mirror and the disk of the apparent 2D tiling
            // gives us "ideal" points on the apparent 2D boundary. These points will be on the new cell mirror.
            Vector3D i1, i2;

            if (2 != Euclidean2D.IntersectionCircleCircle(cellMirrorIdeal, midSphereIdeal, out i1, out i2))
            {
                //throw new System.ArgumentException( "Since we have hyperideal vertices, we should have an intersection with 2 points." );

                // Somehow works in the euclidean case.
                // XXX - Make this better.
                return(H3Models.UHSToBall(new Sphere()
                {
                    Center = Vector3D.DneVector(), Radius = double.NaN
                }));
            }

            double bananaThickness = 0.025;

            //bananaThickness = 0.15;
            bananaThickness = 0.05;

            // Transform the intersection points to a standard Poincare disk.
            // The midsphere radius is the scale of the apparent 2D tilings.
            double   scale  = midSphereIdeal.Radius;
            Vector3D offset = midSphereIdeal.Center;

            i1 -= offset;
            i2 -= offset;
            i1 /= scale;
            i2 /= scale;
            Circle3D banana = H3Models.Ball.OrthogonalCircle(i1, i2);
            Vector3D i3     = H3Models.Ball.ClosestToOrigin(banana);

            i3 = Hyperbolic2D.Offset(i3, -bananaThickness);

            // Transform back.
            i1 *= scale; i2 *= scale; i3 *= scale;
            i1 += offset; i2 += offset; i3 += offset;

            // Construct our new simplex mirror with these 3 points.
            Circle3D c = new Circle3D(i1, i2, i3);

            Sphere result = new Sphere()
            {
                Center = c.Center, Radius = c.Radius
            };

            return(H3Models.UHSToBall(result));
        }
コード例 #12
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);
            }
        }
コード例 #13
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();
                }
            }
        }
コード例 #14
0
 internal static Sphere SphereFuncUHS(Vector3D v)
 {
     return(H3Models.BallToUHS(SphereFuncBall(Geometry.Hyperbolic, H3Models.UHSToBall(v))));
 }
コード例 #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;
                }
            }
        }