// The implementation is approximate but conservative; it always returns // "false" if the cell is not contained by the buffered region, but it may // also return false in some cases where "cell" is in fact contained. public bool Contains(S2Cell cell) { // Return true if the buffered region is guaranteed to cover whole globe. if (radius_successor_ > S1ChordAngle.Straight) { return(true); } // To implement this method perfectly would require computing the directed // Hausdorff distance, which is expensive (and not currently implemented). // However the following heuristic is almost as good in practice and much // cheaper to compute. // Return true if the unbuffered region contains this cell. if (Index().MakeS2ShapeIndexRegion().Contains(cell)) { return(true); } // Otherwise approximate the cell by its bounding cap. // // NOTE(ericv): It would be slightly more accurate to first find the closest // point in the indexed geometry to the cell, and then measure the actual // maximum distance from that point to the cell (a poor man's Hausdorff // distance). But based on actual tests this is not worthwhile. S2Cap cap = cell.GetCapBound(); if (Radius < cap.Radius) { return(false); } // Return true if the distance to the cell center plus the radius of the // cell's bounding cap is less than or equal to "radius_". var target = new S2ClosestEdgeQuery.PointTarget(cell.Center()); return(query_.IsDistanceLess(target, radius_successor_ - cap.Radius)); }
private static Result TestFindClosestEdges(Target target, S2ClosestEdgeQuery query) { List <Result> expected = new(), actual = new(); query.Options_.UseBruteForce = (true); GetClosestEdges(target, query, expected); query.Options_.UseBruteForce = (false); GetClosestEdges(target, query, actual); Assert.True(TestingDistance.CheckDistanceResults(ConvertResults(expected), ConvertResults(actual), query.Options_.MaxResults, query.Options_.MaxDistance, query.Options_.MaxError)); if (!expected.Any()) { return(new Result()); } // Note that when options.max_error() > 0, expected[0].distance() may not // be the minimum distance. It is never larger by more than max_error(), // but the actual value also depends on max_results(). // // Here we verify that GetDistance() and IsDistanceLess() return results // that are consistent with the max_error() setting. var max_error = query.Options_.MaxError; var min_distance = expected[0].Distance; Assert.True(query.GetDistance(target) <= min_distance + max_error); // Test IsDistanceLess(). Assert.False(query.IsDistanceLess(target, min_distance - max_error)); Assert.True(query.IsConservativeDistanceLessOrEqual(target, min_distance)); // Return the closest edge result so that we can also test Project. return(expected[0]); }