예제 #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));
        }
예제 #2
0
        private void CheckBBox(IPoint ctr, double distKm)
        {
            string msg  = "ctr: " + ctr + " distKm: " + distKm;
            double dist = distKm * DistanceUtils.KM_TO_DEG;

            IRectangle r            = Dc().CalcBoxByDistFromPt(ctr, dist, ctx, null);
            double     horizAxisLat = Dc().CalcBoxByDistFromPt_yHorizAxisDEG(ctr, dist, ctx);

            if (!double.IsNaN(horizAxisLat))
            {
                Assert.True(r.RelateYRange(horizAxisLat, horizAxisLat).Intersects());
            }

            //horizontal
            if (r.Width >= 180)
            {
                double deg        = Dc().Distance(ctr, r.MinX, r.MaxY == 90 ? 90 : -90);
                double calcDistKm = deg * DistanceUtils.DEG_TO_KM;
                Assert.True(/*msg,*/ calcDistKm <= distKm + EPS);
                //horizAxisLat is meaningless in this context
            }
            else
            {
                IPoint tPt        = FindClosestPointOnVertToPoint(r.MinX, r.MinY, r.MaxY, ctr);
                double calcDistKm = Dc().Distance(ctr, tPt) * DistanceUtils.DEG_TO_KM;
                CustomAssert.EqualWithDelta(/*msg,*/ distKm, calcDistKm, EPS);
                CustomAssert.EqualWithDelta(/*msg,*/ tPt.Y, horizAxisLat, EPS);
            }

            //vertical
            double topDistKm = Dc().Distance(ctr, ctr.X, r.MaxY) * DistanceUtils.DEG_TO_KM;

            if (r.MaxY == 90)
            {
                Assert.True(/*msg,*/ topDistKm <= distKm + EPS);
            }
            else
            {
                CustomAssert.EqualWithDelta(msg, distKm, topDistKm, EPS);
            }
            double botDistKm = Dc().Distance(ctr, ctr.X, r.MinY) * DistanceUtils.DEG_TO_KM;

            if (r.MinY == -90)
            {
                Assert.True(/*msg,*/ botDistKm <= distKm + EPS);
            }
            else
            {
                CustomAssert.EqualWithDelta(/*msg,*/ distKm, botDistKm, EPS);
            }
        }
예제 #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);
        }