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)); }
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); } }
/// <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); }