public bool Intersects(BoundingCircle bc) { return Intersects(bc.Center, bc.Radius); }
/// <summary> /// Returns true or false depending on whether the segment intersects the bounding circle /// </summary> /// <param name="segment"></param> /// <param name="boundingCircle"></param> /// <returns></returns> public static bool Intersects(this GeoSegment segment, BoundingCircle boundingCircle) { // check if either of the end points of the seg are inside the // circle var d1 = segment[0].DistanceRadians(boundingCircle.Center); if (d1 < boundingCircle.Radius) return true; var d2 = segment[1].DistanceRadians(boundingCircle.Center); if (d2 < boundingCircle.Radius) return true; if (boundingCircle.Center.DistanceToGreatCircle(segment) > boundingCircle.Radius) return false; // calculate point of intersection of great circle containing // (lat, lon) and perpendicular to great circle containing // (lat1, lon1) and (lat2, lon2) var g = segment[0].Cross(segment[1]); var f = boundingCircle.Center.Cross(g); // Reusing g object for i var i = f.Cross(g).Normalized; // check if point of intersection lies on the segment // length of seg var d = segment.LengthRadians; // Make sure the intersection point is inside the exclusion // zone if (boundingCircle.Center.DistanceRadians(i) < boundingCircle.Radius) { // between seg endpoints and first point of intersection var d11 = segment[0].DistanceRadians(i); var d12 = segment[1].DistanceRadians(i); // Check the distance of the intersection point and either // endpoint to see if it falls between them. Add a second // test to make sure that we are on the shorter of the two // segments between the endpoints. return (d11 <= d && d12 <= d && Math.Abs(d11 + d12 - d) < 0.01f); } // Make sure the intersection point is inside the exclusion // zone, reusing i object for i2 var i2 = i.Antipode; if (boundingCircle.Center.DistanceRadians(i2) < boundingCircle.Radius) { // between seg1 endpoints and second point of intersection var d21 = segment[0].DistanceRadians(i2); var d22 = segment[1].DistanceRadians(i2); // Check the distance of the intersection point and either // endpoint to see if it falls between them. Add a second // test to make sure that we are on the shorter of the two // segments between the endpoints. return (d21 <= d && d22 <= d && Math.Abs(d21 + d22 - d) < 0.01f); } return false; }
/** * this can be used to set up the "rest" of the Limit if created from * serialization. just make it public */ void Initialize() { foreach (var geo in Geos) { // this reason we extract a rectangular extents is // for placing random points within the area. if (geo.Latitude < _minLat) _minLat = geo.Latitude; if (geo.Latitude > _maxLat) _maxLat = geo.Latitude; if (geo.Longitude < _minLon) _minLon = geo.Longitude; if (geo.Longitude > _maxLon) _maxLon = geo.Longitude; } // need this for a few things // create a region for testing inside / outside _region = new GeoArray(Geos); // BoundingCircle attempt to get the center of the polygon. when the // shape is not a poly, it hacks a fur ball _boundingCircle = Geos.Count < 3 ? new BoundingCircle(new Geo(0.0, 0.0), 0.0) : new BoundingCircle(_region); _centerOfRegion = _boundingCircle.Center; SetIsClockWise(); }
/// <summary> /// Does the segment come near the region defined by boundingCircle? /// </summary> /// <param name="segment"></param> /// <param name="boundingCircle"></param> /// <param name="near">Radius of approach, in radians</param> /// <returns></returns> public static bool IsNear(this GeoSegment segment, BoundingCircle boundingCircle, double near) { return segment.IsInside(near + boundingCircle.Radius, boundingCircle.Center); }