Example #1
0
        public static double GetNormalizedCircumRadius(int p, double q)
        {
            double hypot = GetTriangleHypotenuse(p, q);

            switch (Geometry2D.GetGeometry(p, q))
            {
            case Geometry.Spherical:
                return(Spherical2D.s2eNorm(hypot) * DiskRadius);

            case Geometry.Euclidean:
                return(EuclideanHypotenuse);

            case Geometry.Hyperbolic:
            {
                if (Infinity.IsInfinite(hypot))
                {
                    return(DiskRadius);
                }

                return(DonHatch.h2eNorm(hypot) * DiskRadius);
            }
            }

            Debug.Assert(false);
            return(1);
        }
Example #2
0
        /// <summary>
        /// Calculates the point of our simplex that is at the middle of a face.
        /// </summary>
        private static Vector3D FaceCenterBall(int p, int q, int r)
        {
            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            switch (cellGeometry)
            {
            case Geometry.Spherical:
            {
                Vector3D cellCenter = CellCenterBall(p, q, r);
                Sphere[] mirrors    = Mirrors(p, q, r, moveToBall: true);
                return(mirrors[0].ProjectToSurface(cellCenter));
            }

            case Geometry.Euclidean:
            {
                Sphere[] mirrors       = Mirrors(p, q, r, moveToBall: false);
                Vector3D faceCenterUHS = mirrors[0].Center;
                faceCenterUHS.Z += mirrors[0].Radius;
                return(H3Models.UHSToBall(faceCenterUHS));
            }

            case Geometry.Hyperbolic:
            {
                throw new System.NotImplementedException();
            }
            }

            throw new System.ArgumentException();
        }
Example #3
0
        /// <summary>
        /// Calculates the point of our simplex that is at the center of a cell.
        /// </summary>
        private static Vector3D CellCenterBall(int p, int q, int r)
        {
            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            switch (cellGeometry)
            {
            case Geometry.Spherical:
            {
                return(new Vector3D());
            }

            case Geometry.Euclidean:
            {
                return(new Vector3D(0, 0, 1));
            }

            case Geometry.Hyperbolic:
            {
                //throw new System.NotImplementedException();
                return(new Vector3D(0, 0, 1));
            }
            }

            throw new System.ArgumentException();
        }
Example #4
0
        /// <summary>
        /// Calculates the point of our simplex that is at a vertex.
        /// </summary>
        public static Vector3D VertexPointBall(int p, int q, int r)
        {
            Geometry vertexGeometry = Geometry2D.GetGeometry(q, r);

            if (vertexGeometry == Geometry.Hyperbolic)
            {
                // Outside the ball, and not in a good way.  Use the Klein version.
                //throw new System.NotImplementedException();
                return(new Vector3D(0, 0, -1));
            }

            // Get in UHS first.
            Sphere cellFacet = Mirrors(p, q, r, moveToBall: false).First();
            double rSquared  = Math.Pow(cellFacet.Radius, 2);
            double cSquared  = Math.Pow(cellFacet.Center.Abs(), 2);

            Vector3D uhs;

            if (Tolerance.Equal(rSquared, cSquared))                    // e.g. 363
            {
                uhs = new Vector3D();
            }
            else
            {
                double height = Math.Sqrt(rSquared - cSquared);
                uhs = new Vector3D(0, 0, height);
            }
            return(H3Models.UHSToBall(uhs));
        }
Example #5
0
        public TilingConfig(int p, int q) : this()
        {
            if (Geometry2D.GetGeometry(p, q) != Geometry.Spherical)
            {
                throw new System.ArgumentException();
            }

            SetupConfig(p, q, PlatonicSolids.NumFacets(p, q));
        }
Example #6
0
        /// <summary>
        /// Get the side length opposite angle PI/P,
        /// In the induced geometry.
        /// </summary>
        public static double GetTrianglePSide(int p, int q)
        {
            Geometry g = Geometry2D.GetGeometry(p, q);

            double alpha = Math.PI / 2;
            double beta  = Math.PI / q;
            double gamma = Math.PI / p;                 // The one we want.

            if (g == Geometry.Euclidean)
            {
                return(EuclideanHypotenuse * Math.Sin(gamma));
            }
            return(GetTriangleSide(g, gamma, beta, alpha));
        }
Example #7
0
        public static Mobius FCOrientMobius(int p, int q)
        {
            Vector3D p1, p2, p3;
            Segment  seg = null;

            TilePoints(p, q, out p1, out p2, out p3, out seg);
            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            p1.RotateXY(Math.PI / 2);                   // XXX - repeated from above.  Implement a better way to sequence transformations.

            Mobius m = new Mobius();

            m.Isometry(cellGeometry, 0, -p1);
            return(m);
        }
Example #8
0
        /// <summary>
        /// Get the side length opposite angle PI/Q,
        /// In the induced geometry.
        /// </summary>
        public static double GetTriangleQSide(int p, int q)
        {
            Geometry g = Geometry2D.GetGeometry(p, q);

            double alpha = Math.PI / 2;
            double beta  = PiOverNSafe(q);              // The one we want.
            double gamma = PiOverNSafe(p);

            if (g == Geometry.Euclidean)
            {
                return(EuclideanHypotenuse * Math.Sin(beta));
            }

            return(GetTriangleSide(g, beta, gamma, alpha));
        }
Example #9
0
        public static Vector3D VertexPointKlein(int p, int q, int r)
        {
            Geometry vertexGeometry = Geometry2D.GetGeometry(q, r);

            if (vertexGeometry != Geometry.Hyperbolic)
            {
                throw new System.NotImplementedException();
            }

            Sphere[] mirrors = Mirrors(p, q, r);
            Sphere   klein   = H3Models.BallToKlein(mirrors[0]);
            Vector3D off     = klein.Offset;
            double   h       = off.Abs() / Math.Cos(off.AngleTo(new Vector3D(0, 0, -1)));

            return(new Vector3D(0, 0, -h));
        }
Example #10
0
        public static Mobius VertexCenteredMobius(int p, int q)
        {
            double angle = Math.PI / q;

            if (Utils.Even(q))
            {
                angle *= 2;
            }
            Vector3D offset = new Vector3D(-1 * Geometry2D.GetNormalizedCircumRadius(p, q), 0, 0);

            offset.RotateXY(angle);
            Mobius m = new Mobius();

            m.Isometry(Geometry2D.GetGeometry(p, q), angle, offset.ToComplex());
            return(m);
        }
Example #11
0
        /// <summary>
        /// In the induced geometry.
        /// </summary>
        public static double GetTriangleHypotenuse(int p, int q)
        {
            Geometry g = Geometry2D.GetGeometry(p, q);

            if (g == Geometry.Euclidean)
            {
                return(EuclideanHypotenuse);
            }

            // We have a 2,q,p triangle, where the right angle alpha
            // is opposite the hypotenuse (the length we want).
            double alpha = Math.PI / 2;
            double beta  = Math.PI / q;
            double gamma = Math.PI / p;

            return(GetTriangleSide(g, alpha, beta, gamma));
        }
Example #12
0
        /// <summary>
        /// This Mobius transform will center the tiling on an edge.
        /// </summary>
        public Mobius EdgeMobius()
        {
            Geometry g = Geometry2D.GetGeometry(this.P, this.Q);

            Polygon poly = new Polygon();

            poly.CreateRegular(this.P, this.Q);
            Segment  seg    = poly.Segments[0];
            Vector3D offset = seg.Midpoint;

            double angle = Math.PI / this.P;

            offset.RotateXY(-angle);

            Mobius m = new Mobius();

            m.Isometry(g, -angle, -offset);
            return(m);
        }
Example #13
0
        public static double GetNormalizedCircumRadius(int p, int q)
        {
            Geometry g = Geometry2D.GetGeometry(p, q);

            double hypot = GetTriangleHypotenuse(p, q);

            switch (g)
            {
            case Geometry.Spherical:
                return(Spherical2D.s2eNorm(hypot) * DiskRadius);

            case Geometry.Euclidean:
                return(EuclideanHypotenuse);

            case Geometry.Hyperbolic:
                return(DonHatch.h2eNorm(hypot) * DiskRadius);
            }

            Debug.Assert(false);
            return(1);
        }
Example #14
0
        /// <summary>
        /// Calculates the point of our simplex that is at the middle of an edge.
        /// </summary>
        private static Vector3D MidEdgePointBall(int p, int q, int r)
        {
            // We need the mid-radius, but we have to do the calculation
            // with our Euclidean simplex mirrors (to avoid infinities that happen in the formulas).
            Circle3D edge = HoneycombEdgeUHS(p, q, r);

            if (edge.Radius == 0)
            {
                return(edge.Center);
            }

            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            switch (cellGeometry)
            {
            case Geometry.Spherical:
            {
                Sphere sphereInBall = H3Models.UHSToBall(new Sphere()
                    {
                        Center = edge.Center, Radius = edge.Radius
                    });
                Vector3D mid = sphereInBall.ProjectToSurface(new Vector3D());                           // Project origin to sphere.
                return(mid);
            }

            case Geometry.Euclidean:
            {
                Vector3D mid = H3Models.UHSToBall(edge.Center + new Vector3D(0, 0, edge.Radius));
                return(mid);
            }

            case Geometry.Hyperbolic:
            {
                throw new System.NotImplementedException();
            }
            }

            throw new System.ArgumentException();
        }
Example #15
0
        /// <summary>
        /// Calculates the 3 mirrors connected to the cell center.
        /// This works in all geometries and returns results in the UHS model (or the appropriate analogue).
        /// </summary>
        private static Sphere[] InteriorMirrors(int p, int q)
        {
            // Some construction points we need.
            Vector3D p1, p2, p3;
            Segment  seg = null;

            TilePoints(p, q, out p1, out p2, out p3, out seg);

            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            // XZ-plane
            Sphere s1 = new Sphere()
            {
                Center = new Vector3D(0, 1, 0),
                Radius = double.PositiveInfinity
            };

            Sphere s2 = null;

            if (cellGeometry == Geometry.Euclidean)
            {
                s2 = new Sphere()
                {
                    Center = -p2,
                    Offset = p2,
                    Radius = double.PositiveInfinity
                };
            }
            else if (
                cellGeometry == Geometry.Spherical ||
                cellGeometry == Geometry.Hyperbolic)
            {
                s2 = new Sphere()
                {
                    Center = seg.Center,
                    Radius = seg.Radius,
                    //Invert = true	// XXX - maybe we don't invert in the case of spherical?
                };

                // j34

                /*double off = seg.Center.Abs() - seg.Radius;
                 * off *= 1.05;
                 * Vector3D vOff = seg.Center;
                 * vOff.Normalize();
                 * vOff *= off;
                 * s2 = H3Models.Ball.OrthogonalSphereInterior( vOff );*/

                // 4j3

                /*double off = seg.Center.Abs() - seg.Radius;
                 * off = DonHatch.h2eNorm( DonHatch.e2hNorm( off ) + m_jOffset );
                 * Vector3D vOff = seg.Center;
                 * vOff.Normalize();
                 * vOff *= off;
                 * s2 = H3Models.Ball.OrthogonalSphereInterior( vOff );*/
            }

            Sphere s3;

            if (Infinite(p) && Infinite(q) /*&& FiniteOrInfinite( r )*/)
            {
                Vector3D tempCenter = seg.Center;
                tempCenter.X *= -1;
                s3            = new Sphere()
                {
                    Center = tempCenter,
                    Radius = seg.Radius,
                    //Invert = true,
                };
            }
            else
            {
                s3 = new Sphere()
                {
                    Center = p3,
                    Radius = double.PositiveInfinity
                };
            }

            // The reason for the special case ordering is to make sure
            // the last mirror is always the cell-reflecting mirror of the dual honeycomb.
            // The order we want are the mirrors opposite: cell, face, edge, vertex
            // NOTE: This also puts the mirrors in the same order as in standard presentations,
            // e.g. from Coxeter's 57-cell paper.
            Sphere[] surfaces;
            if (!Infinite(p) && Infinite(q))
            {
                surfaces = new Sphere[] { s2, s1, s3 }
            }
            ;
            else
            {
                surfaces = new Sphere[] { s3, s1, s2 }
            };

            return(surfaces);
        }
Example #16
0
        public void CreateRegular(int numSides, int q)
        {
            int p = numSides;

            Segments.Clear();
            List <Vector3D> points = new List <Vector3D>();

            Geometry g            = Geometry2D.GetGeometry(p, q);
            double   circumRadius = Geometry2D.GetNormalizedCircumRadius(p, q);

            double angle = 0;

            for (int i = 0; i < p; i++)
            {
                Vector3D point = new Vector3D();
                point.X = (circumRadius * Math.Cos(angle));
                point.Y = (circumRadius * Math.Sin(angle));
                points.Add(point);
                angle += Utils.DegreesToRadians(360.0 / p);
            }

            // Turn this into segments.
            for (int i = 0; i < points.Count; i++)
            {
                int     idx1       = i;
                int     idx2       = i == points.Count - 1 ? 0 : i + 1;
                Segment newSegment = new Segment();
                newSegment.P1 = points[idx1];
                newSegment.P2 = points[idx2];

                if (g != Geometry.Euclidean)
                {
                    newSegment.Type = SegmentType.Arc;

                    if (2 == p)
                    {
                        // Our magic formula below breaks down for digons.
                        double factor = Math.Tan(Math.PI / 6);
                        newSegment.Center = newSegment.P1.X > 0 ?
                                            new Vector3D(0, -circumRadius, 0) * factor :
                                            new Vector3D(0, circumRadius, 0) * factor;
                    }
                    else
                    {
                        // Our segments are arcs in Non-Euclidean geometries.
                        // Magically, the same formula turned out to work for both.
                        // (Maybe this is because the Poincare Disc model of the
                        // hyperbolic plane is stereographic projection as well).

                        double piq    = q == -1 ? 0 : Math.PI / q;                      // Handle q infinite.
                        double t1     = Math.PI / p;
                        double t2     = Math.PI / 2 - piq - t1;
                        double factor = (Math.Tan(t1) / Math.Tan(t2) + 1) / 2;
                        newSegment.Center = (newSegment.P1 + newSegment.P2) * factor;
                    }

                    newSegment.Clockwise = Geometry.Spherical == g ? false : true;
                }

                // XXX - Make this configurable?
                // This is the color of cell boundary lines.
                //newSegment.m_color = CColor( 1, 1, 0, 1 );
                Segments.Add(newSegment);
            }
        }
Example #17
0
        public static Sphere[] Mirrors(int p, int q, int r, ref Vector3D cellCenter, bool moveToBall = true, double scaling = -1)
        {
            Geometry g = Util.GetGeometry(p, q, r);

            if (g == Geometry.Spherical)
            {
                // These are in the ball model.
                Sphere[] result = SimplexCalcs.MirrorsSpherical(p, q, r);
                return(result);
            }
            else if (g == Geometry.Euclidean)
            {
                return(SimplexCalcs.MirrorsEuclidean());
            }

            // This is a rotation we'll apply to the mirrors at the end.
            // This is to try to make our image outputs have vertical bi-lateral symmetry and the most consistent in all cases.
            // NOTE: + is CW, not CCW. (Because the way I did things, our images have been reflected vertically, and I'm too lazy to go change this.)
            double rotation = Math.PI / 2;

            // Some construction points we need.
            Vector3D p1, p2, p3;
            Segment  seg = null;

            TilePoints(p, q, out p1, out p2, out p3, out seg);

            //
            // Construct in UHS
            //

            Geometry cellGeometry = Geometry2D.GetGeometry(p, q);

            Vector3D center = new Vector3D();
            double   radius = 0;

            if (cellGeometry == Geometry.Spherical)
            {
                // Finite or Infinite r

                // Spherical trig
                double halfSide = Geometry2D.GetTrianglePSide(q, p);
                double mag      = Math.Sin(halfSide) / Math.Cos(Util.PiOverNSafe(r));
                mag = Math.Asin(mag);

                // e.g. 43j
                //mag *= 0.95;

                // Move mag to p1.
                mag = Spherical2D.s2eNorm(mag);
                H3Models.Ball.DupinCyclideSphere(p1, mag, Geometry.Spherical, out center, out radius);
            }
            else if (cellGeometry == Geometry.Euclidean)
            {
                center = p1;
                radius = p1.Dist(p2) / Math.Cos(Util.PiOverNSafe(r));
            }
            else if (cellGeometry == Geometry.Hyperbolic)
            {
                if (Infinite(p) && Infinite(q) && FiniteOrInfinite(r))
                {
                    //double iiiCellRadius = 2 - Math.Sqrt( 2 );
                    //Circle3D iiiCircle = new Circle3D() { Center = new Vector3D( 1 - iiiCellRadius, 0, 0 ), Radius = iiiCellRadius };
                    //radius = iiiCellRadius;	// infinite r
                    //center = new Vector3D( 1 - radius, 0, 0 );

                    // For finite r, it was easier to calculate cell facet in a more symmetric position,
                    // then move into position with the other mirrors via a Mobius transformation.
                    double rTemp = 1 / (Math.Cos(Util.PiOverNSafe(r)) + 1);
                    Mobius m     = new Mobius();
                    m.Isometry(Geometry.Hyperbolic, -Math.PI / 4, new Vector3D(0, Math.Sqrt(2) - 1));
                    Vector3D c1 = m.Apply(new Vector3D(1 - 2 * rTemp, 0, 0));
                    Vector3D c2 = c1;
                    c2.Y *= -1;
                    Vector3D c3 = new Vector3D(1, 0);
                    Circle3D c  = new Circle3D(c1, c2, c3);

                    radius = c.Radius;
                    center = c.Center;
                }
                else if (Infinite(p) && Finite(q) && FiniteOrInfinite(r))
                {
                    // http://www.wolframalpha.com/input/?i=r%2Bx+%3D+1%2C+sin%28pi%2Fp%29+%3D+r%2Fx%2C+solve+for+r
                    // radius = 2 * Math.Sqrt( 3 ) - 3;	// Appolonian gasket wiki page
                    //radius = Math.Sin( Math.PI / q ) / ( Math.Sin( Math.PI / q ) + 1 );
                    //center = new Vector3D( 1 - radius, 0, 0 );

                    // For finite r, it was easier to calculate cell facet in a more symmetric position,
                    // then move into position with the other mirrors via a Mobius transformation.
                    double rTemp = 1 / (Math.Cos(Util.PiOverNSafe(r)) + 1);
                    Mobius m     = new Mobius();
                    m.Isometry(Geometry.Hyperbolic, 0, p2);
                    Vector3D findingAngle = m.Inverse().Apply(new Vector3D(1, 0));
                    double   angle        = Math.Atan2(findingAngle.Y, findingAngle.X);

                    m.Isometry(Geometry.Hyperbolic, angle, p2);
                    Vector3D c1 = m.Apply(new Vector3D(1 - 2 * rTemp, 0, 0));
                    Vector3D c2 = c1;
                    c2.Y *= -1;
                    Vector3D c3 = new Vector3D(1, 0);
                    Circle3D c  = new Circle3D(c1, c2, c3);

                    radius = c.Radius;
                    center = c.Center;
                }
                else if (Finite(p) && Infinite(q) && FiniteOrInfinite(r))
                {
                    radius = p2.Abs();                                                                              // infinite r
                    radius = DonHatch.asinh(Math.Sinh(DonHatch.e2hNorm(p2.Abs())) / Math.Cos(Util.PiOverNSafe(r))); // hyperbolic trig

                    // 4j3
                    //m_jOffset = radius * 0.02;
                    //radius += m_jOffset ;

                    radius    = DonHatch.h2eNorm(radius);
                    center    = new Vector3D();
                    rotation *= -1;
                }
                else if (/*Finite( p ) &&*/ Finite(q))
                {
                    // Infinite r
                    //double mag = Geometry2D.GetTrianglePSide( q, p );

                    // Finite or Infinite r
                    double halfSide = Geometry2D.GetTrianglePSide(q, p);
                    double mag      = DonHatch.asinh(Math.Sinh(halfSide) / Math.Cos(Util.PiOverNSafe(r)));                              // hyperbolic trig
                    H3Models.Ball.DupinCyclideSphere(p1, DonHatch.h2eNorm(mag), out center, out radius);
                }
                else
                {
                    throw new System.NotImplementedException();
                }
            }
            Sphere cellBoundary = new Sphere()
            {
                Center = center,
                Radius = radius
            };

            Sphere[] interior = InteriorMirrors(p, q);
            Sphere[] surfaces = new Sphere[] { cellBoundary, interior[0], interior[1], interior[2] };

            // Apply rotations.
            bool applyRotations = true;

            if (applyRotations)
            {
                foreach (Sphere s in surfaces)
                {
                    RotateSphere(s, rotation);
                }
                p1.RotateXY(rotation);
            }

            // Apply scaling
            bool applyScaling = scaling != -1;

            if (applyScaling)
            {
                //double scale = 1.0/0.34390660467269524;
                //scale = 0.58643550768408892;
                foreach (Sphere s in surfaces)
                {
                    Sphere.ScaleSphere(s, scaling);
                }
            }

            bool facetCentered = false;

            if (facetCentered)
            {
                PrepForFacetCentering(p, q, surfaces, ref cellCenter);
            }

            // Move to ball if needed.
            if (moveToBall)
            {
                surfaces = MoveToBall(surfaces, ref cellCenter);
            }

            return(surfaces);
        }
Example #18
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);
        }