示例#1
0
    // 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));
    }
示例#2
0
        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]);
        }