Exemple #1
0
        private IRectangle IntersectRects(IRectangle r1, IRectangle r2)
        {
            Debug.Assert(r1.Relate(r2).Intersects());
            double minX, maxX;

            if (r1.RelateXRange(r2.MinX, r2.MinX).Intersects())
            {
                minX = r2.MinX;
            }
            else
            {
                minX = r1.MinX;
            }
            if (r1.RelateXRange(r2.MaxX, r2.MaxX).Intersects())
            {
                maxX = r2.MaxX;
            }
            else
            {
                maxX = r1.MaxX;
            }
            double minY, maxY;

            if (r1.RelateYRange(r2.MinY, r2.MinY).Intersects())
            {
                minY = r2.MinY;
            }
            else
            {
                minY = r1.MinY;
            }
            if (r1.RelateYRange(r2.MaxY, r2.MaxY).Intersects())
            {
                maxY = r2.MaxY;
            }
            else
            {
                maxY = r1.MaxY;
            }
            return(ctx.MakeRectangle(minX, maxX, minY, maxY));
        }
Exemple #2
0
        private SpatialRelation RelateRectangleCircleWrapsPole(IRectangle r, SpatialContext ctx)
        {
            //This method handles the case where the circle wraps ONE pole, but not both.  For both,
            // there is the inverseCircle case handled before now.  The only exception is for the case where
            // the circle covers the entire globe, and we'll check that first.
            if (radiusDEG == 180)            //whole globe
            {
                return(SpatialRelation.CONTAINS);
            }

            //Check if r is within the pole wrap region:
            double yTop = Center.Y + radiusDEG;

            if (yTop > 90)
            {
                double yTopOverlap = yTop - 90;
                Debug.Assert(yTopOverlap <= 90, "yTopOverlap: " + yTopOverlap);
                if (r.MinY >= 90 - yTopOverlap)
                {
                    return(SpatialRelation.CONTAINS);
                }
            }
            else
            {
                double yBot = point.Y - radiusDEG;
                if (yBot < -90)
                {
                    double yBotOverlap = -90 - yBot;
                    Debug.Assert(yBotOverlap <= 90);
                    if (r.MaxY <= -90 + yBotOverlap)
                    {
                        return(SpatialRelation.CONTAINS);
                    }
                }
                else
                {
                    //This point is probably not reachable ??
                    Debug.Assert(yTop == 90 || yBot == -90);                    //we simply touch a pole
                    //continue
                }
            }

            //If there are no corners to check intersection because r wraps completely...
            if (r.Width == 360)
            {
                return(SpatialRelation.INTERSECTS);
            }

            //Check corners:
            int cornersIntersect = NumCornersIntersect(r);
            // (It might be possible to reduce contains() calls within nCI() to exactly two, but this intersection
            //  code is complicated enough as it is.)
            double frontX = Center.X;

            if (cornersIntersect == 4)
            {            //all
                double backX = frontX <= 0 ? frontX + 180 : frontX - 180;
                if (r.RelateXRange(backX, backX).Intersects())
                {
                    return(SpatialRelation.INTERSECTS);
                }
                else
                {
                    return(SpatialRelation.CONTAINS);
                }
            }
            else if (cornersIntersect == 0)
            {            //none
                if (r.RelateXRange(frontX, frontX).Intersects())
                {
                    return(SpatialRelation.INTERSECTS);
                }
                else
                {
                    return(SpatialRelation.DISJOINT);
                }
            }
            else            //partial
            {
                return(SpatialRelation.INTERSECTS);
            }
        }
Exemple #3
0
        /// <summary>
        /// Called after bounding box is intersected.
        /// </summary>
        /// <param name="r"></param>
        /// <param name="bboxSect"><see cref="SpatialRelation.INTERSECTS"/> or <see cref="SpatialRelation.CONTAINS"/> from enclosingBox's intersection</param>
        /// <returns><see cref="SpatialRelation.DISJOINT"/>, <see cref="SpatialRelation.CONTAINS"/>, or
        /// <see cref="SpatialRelation.INTERSECTS"/> (not <see cref="SpatialRelation.WITHIN"/>)</returns>
        protected override SpatialRelation RelateRectanglePhase2(IRectangle r, SpatialRelation bboxSect)
        {
            if (inverseCircle != null)
            {
                return(inverseCircle.Relate(r).Inverse());
            }

            //if a pole is wrapped, we have a separate algorithm
            if (enclosingBox.Width == 360)
            {
                return(RelateRectangleCircleWrapsPole(r, ctx));
            }

            //This is an optimization path for when there are no dateline or pole issues.
            if (!enclosingBox.CrossesDateLine && !r.CrossesDateLine)
            {
                return(base.RelateRectanglePhase2(r, bboxSect));
            }

            //Rectangle wraps around the world longitudinally creating a solid band; there are no corners to test intersection
            if (r.Width == 360)
            {
                return(SpatialRelation.INTERSECTS);
            }

            //do quick check to see if all corners are within this circle for CONTAINS
            int cornersIntersect = NumCornersIntersect(r);

            if (cornersIntersect == 4)
            {
                //ensure r's x axis is within c's.  If it doesn't, r sneaks around the globe to touch the other side (intersect).
                SpatialRelation xIntersect = r.RelateXRange(enclosingBox.MinX, enclosingBox.MaxX);
                if (xIntersect == SpatialRelation.WITHIN)
                {
                    return(SpatialRelation.CONTAINS);
                }
                return(SpatialRelation.INTERSECTS);
            }

            //INTERSECT or DISJOINT ?
            if (cornersIntersect > 0)
            {
                return(SpatialRelation.INTERSECTS);
            }

            //Now we check if one of the axis of the circle intersect with r.  If so we have
            // intersection.

            /* x axis intersects  */
            if (r.RelateYRange(YAxis, YAxis).Intersects() &&          // at y vertical
                r.RelateXRange(enclosingBox.MinX, enclosingBox.MaxX).Intersects())
            {
                return(SpatialRelation.INTERSECTS);
            }

            /* y axis intersects */
            if (r.RelateXRange(XAxis, XAxis).Intersects())
            {             // at x horizontal
                double yTop = Center.Y + radiusDEG;
                Debug.Assert(yTop <= 90);
                double yBot = Center.Y - radiusDEG;
                Debug.Assert(yBot >= -90);
                if (r.RelateYRange(yBot, yTop).Intersects())                //back bottom
                {
                    return(SpatialRelation.INTERSECTS);
                }
            }

            return(SpatialRelation.DISJOINT);
        }