Exemple #1
0
        /// <summary>s
        /// Checks if the point is inside our hexagon,
        /// but takes advantage of things we know to make it faster.
        /// The generic polygon check is way too slow.
        /// This is meant to be used during puzzle building.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool IsPointInsideOptimized(Vector3D p)
        {
            if (!CircumCircle.IsPointInsideFast(p))
            {
                return(false);
            }

            // We will check that we are on the same side of every segment as the center.
            Vector3D cen = Hexagon.Center;

            foreach (Segment s in Hexagon.Segments)
            {
                if (s.Type == SegmentType.Line)
                {
                    if (!Euclidean2D.SameSideOfLine(s.P1, s.P2, cen, p))
                    {
                        return(false);
                    }
                }
                else
                {
                    bool inside1 = s.Circle.IsPointInside(cen);
                    bool inside2 = s.Circle.IsPointInside(p);
                    if (inside1 ^ inside2)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Helper to check if we will affect a sticker, and cache in our list if so.
        /// </summary>
        public void WillAffectSticker(Sticker sticker, bool sphericalPuzzle)
        {
            if (AffectedStickers == null)
            {
                AffectedStickers = new List <StickerList>();
                for (int slice = 0; slice < this.NumSlices; slice++)
                {
                    AffectedStickers.Add(new List <Sticker>());
                }
            }

            if (Earthquake)
            {
                Vector3D cen = sticker.Poly.Center;
                if (Pants.IsPointInsideOptimized(cen))
                {
                    AffectedStickers[0].Add(sticker);
                }
                return;
            }

            // Slices are ordered by depth.
            // We cycle from the inner slice outward.
            for (int slice = 0; slice < this.Circles.Length; slice++)
            {
                CircleNE circle   = this.Circles[slice];
                bool     isInside = sphericalPuzzle ?
                                    circle.IsPointInsideNE(sticker.Poly.Center) :
                                    circle.IsPointInsideFast(sticker.Poly.Center);
                if (isInside)
                {
                    AffectedStickers[slice].Add(sticker);
                    return;
                }
            }

            // If we made it here for spherical puzzles, we are in the last slice.
            // Second check was needed for {3,5} 8C
            if (sphericalPuzzle &&
                (this.NumSlices != this.Circles.Length))
            {
                AffectedStickers[this.NumSlices - 1].Add(sticker);
            }
        }