Пример #1
0
        /// <summary>
        /// Helper to construct some points we need for calculating simplex facets for a {p,q,r} honeycomb.
        /// </summary>
        private static void TilePoints(int p, int q, out Vector3D p1, out Vector3D p2, out Vector3D p3, out Segment seg)
        {
            if (Infinite(p) && Infinite(q) /*&& FiniteOrInfinite( r )*/)
            {
                p1 = new Vector3D(1, 0, 0);
                p2 = new Vector3D(0, Math.Sqrt(2) - 1);
                p3 = Vector3D.DneVector();

                Circle3D arcCircle;
                H3Models.Ball.OrthogonalCircleInterior(p2, p1, out arcCircle);
                seg = Segment.Arc(p1, p2, arcCircle.Center, clockwise: true);
            }
            else
            {
                Segment[] baseTileSegments;
                if (Infinite(q))
                {
                    baseTileSegments = BaseTileSegments(p, q);                          // Can't use dual here.
                }
                else
                {
                    baseTileSegments = BaseTileSegments(q, p);                          // Intentionally using dual.
                }
                seg = baseTileSegments.First();

                p1 = seg.P1;
                p2 = seg.Midpoint;
                p3 = p2;
                p3.RotateXY(-Math.PI / 2);
            }
        }
Пример #2
0
        /// <summary>
        /// Helper to return the smaller spliced arc.
        /// </summary>
        private static Segment SmallerSplicedArc(Circle c, List <IntersectionPoint> iPoints, ref int pair, bool increment, ref int nextSegIndex)
        {
            IntersectionPoint iPoint1, iPoint2;

            GetPairPoints(iPoints, pair, increment, out iPoint1, out iPoint2);

            Vector3D p1 = iPoint1.Location;
            Vector3D p2 = iPoint2.Location;

            nextSegIndex = iPoint2.Index;

            Segment newSeg = Segment.Arc(p1, p2, c.Center, clockwise: true);

            if (newSeg.Angle > System.Math.PI)
            {
                newSeg.Clockwise = false;
            }

            pair++;
            if (pair == iPoints.Count / 2)
            {
                pair = 0;
            }

            return(newSeg);
        }
Пример #3
0
        public static Polygon Heart()
        {
            Polygon newPoly = new Polygon();
            double  size    = 0.12;
            double  angle   = -3 * Math.PI / 2;

            Vector3D p1 = new Vector3D(0, -1.5 * size);
            Vector3D p2 = new Vector3D(-size, 0);
            Vector3D p3 = new Vector3D(-size / 2, size);
            Vector3D p4 = new Vector3D(0, size / 2);
            Vector3D p5 = new Vector3D(size / 2, size);
            Vector3D p6 = new Vector3D(size, 0);

            p1.RotateXY(angle);
            p2.RotateXY(angle);
            p3.RotateXY(angle);
            p4.RotateXY(angle);
            p5.RotateXY(angle);
            p6.RotateXY(angle);

            newPoly.Segments.Add(Segment.Line(p1, p2));
            newPoly.Segments.Add(Segment.Arc(p2, p3, p4));
            newPoly.Segments.Add(Segment.Arc(p4, p5, p6));
            newPoly.Segments.Add(Segment.Line(p6, p1));
            return(newPoly);
        }
Пример #4
0
        /// <summary>
        /// Slicing function used for earthquake puzzles.
        /// c should be geodesic (orthogonal to the disk boundary).
        /// </summary>
        public static void SlicePolygonWithHyperbolicGeodesic(Polygon p, CircleNE c, double thickness, out List <Polygon> output)
        {
            Geometry g = Geometry.Hyperbolic;

            Segment seg = null;

            if (c.IsLine)
            {
                Vector3D p1, p2;
                Euclidean2D.IntersectionLineCircle(c.P1, c.P2, new Circle(), out p1, out p2);
                seg = Segment.Line(p1, p2);
            }
            else
            {
                // Setup the two slicing circles.
                // These are cuts equidistant from the passed in geodesic.
                Vector3D closestToOrigin = H3Models.Ball.ClosestToOrigin(new Circle3D()
                {
                    Center = c.Center, Radius = c.Radius, Normal = new Vector3D(0, 0, 1)
                });

                Vector3D p1, p2;
                Euclidean2D.IntersectionCircleCircle(c, new Circle(), out p1, out p2);
                seg = Segment.Arc(p1, closestToOrigin, p2);
            }

            Circle c1 = H3Models.Ball.EquidistantOffset(g, seg, thickness / 2);
            Circle c2 = H3Models.Ball.EquidistantOffset(g, seg, -thickness / 2);

            CircleNE c1NE = c.Clone(), c2NE = c.Clone();

            c1NE.Center = c1.Center; c2NE.Center = c2.Center;
            c1NE.Radius = c1.Radius; c2NE.Radius = c2.Radius;
            SlicePolygonHelper(p, c1NE, c2NE, out output);
        }
Пример #5
0
        /// <summary>
        /// Euclidean scale us relative to some center point.
        /// NOTE: Currently only works for line segments.
        /// </summary>
        public void Scale(Vector3D center, double factor)
        {
            Translate(-center);
            if (this.Type == SegmentType.Line)
            {
                this.P1 *= factor;
                this.P2 *= factor;
            }
            else if (this.Type == SegmentType.Arc)
            {
                Vector3D p1  = this.P1;
                Vector3D p2  = this.P2;
                Vector3D mid = this.Midpoint;
                p1  *= factor;
                p2  *= factor;
                mid *= factor;
                Segment temp = Segment.Arc(p1, mid, p2);

                this.P1     = p1;
                this.P2     = p2;
                this.Center = temp.Center;
            }
            Translate(center);
        }