Beispiel #1
0
    // Given a point X and an edge AB, check that the distance from X to AB is
    // "distance_radians" and the closest point on AB is "expected_closest".
    private static void CheckDistance(S2Point x, S2Point a, S2Point b, double distance_radians, S2Point expected_closest)
    {
        x = x.Normalize();
        a = a.Normalize();
        b = b.Normalize();
        expected_closest = expected_closest.Normalize();
        Assert2.Near(distance_radians, S2.GetDistance(x, a, b).Radians, S2.DoubleError);
        S2Point closest = S2.Project(x, a, b);

        Assert.True(S2Pred.CompareEdgeDistance(
                        closest, a, b, new S1ChordAngle(S2.kProjectPerpendicularErrorS1Angle)) < 0);

        // If X is perpendicular to AB then there is nothing further we can expect.
        if (distance_radians != S2.M_PI_2)
        {
            if (expected_closest == new S2Point())
            {
                // This special value says that the result should be A or B.
                Assert.True(closest == a || closest == b);
            }
            else
            {
                Assert.True(S2.ApproxEquals(closest, expected_closest));
            }
        }
        S1ChordAngle min_distance = S1ChordAngle.Zero;

        Assert.False(S2.UpdateMinDistance(x, a, b, ref min_distance));
        min_distance = S1ChordAngle.Infinity;
        Assert.True(S2.UpdateMinDistance(x, a, b, ref min_distance));
        Assert2.Near(distance_radians, min_distance.ToAngle().Radians, S2.DoubleError);
    }
Beispiel #2
0
    private static S1Angle BruteForceDistance(S2LatLngRect a, S2LatLngRect b)
    {
        if (a.Intersects(b))
        {
            return(S1Angle.FromRadians(0));
        }

        // Compare every point in 'a' against every latitude edge and longitude edge
        // in 'b', and vice-versa, for a total of 16 point-vs-latitude-edge tests and
        // 16 point-vs-longitude-edge tests.
        var pnt_a = new S2LatLng[4];
        var pnt_b = new S2LatLng[4];

        pnt_a[0] = new S2LatLng(a.LatLo(), a.LngLo());
        pnt_a[1] = new S2LatLng(a.LatLo(), a.LngHi());
        pnt_a[2] = new S2LatLng(a.LatHi(), a.LngHi());
        pnt_a[3] = new S2LatLng(a.LatHi(), a.LngLo());
        pnt_b[0] = new S2LatLng(b.LatLo(), b.LngLo());
        pnt_b[1] = new S2LatLng(b.LatLo(), b.LngHi());
        pnt_b[2] = new S2LatLng(b.LatHi(), b.LngHi());
        pnt_b[3] = new S2LatLng(b.LatHi(), b.LngLo());

        // Make arrays containing the lo/hi latitudes and the lo/hi longitude edges.
        var lat_a = new S1Angle[2] {
            a.LatLo(), a.LatHi()
        };
        var lat_b = new S1Angle[2] {
            b.LatLo(), b.LatHi()
        };
        var lng_edge_a = new S2Point[][] { new S2Point[] { pnt_a[0].ToPoint(), pnt_a[3].ToPoint() },
                                           new S2Point[] { pnt_a[1].ToPoint(), pnt_a[2].ToPoint() } };
        var lng_edge_b = new S2Point[][] { new S2Point[] { pnt_b[0].ToPoint(), pnt_b[3].ToPoint() },
                                           new S2Point[] { pnt_b[1].ToPoint(), pnt_b[2].ToPoint() } };

        S1Angle min_distance = S1Angle.FromDegrees(180.0);

        for (int i = 0; i < 4; ++i)
        {
            // For each point in a and b.
            var current_a = pnt_a[i];
            var current_b = pnt_b[i];

            for (int j = 0; j < 2; ++j)
            {
                // Get distances to latitude and longitude edges.
                S1Angle a_to_lat = GetDistance(current_a, lat_b[j], b.Lng);
                S1Angle b_to_lat = GetDistance(current_b, lat_a[j], a.Lng);
                S1Angle a_to_lng = S2.GetDistance(current_a.ToPoint(), lng_edge_b[j][0], lng_edge_b[j][1]);
                S1Angle b_to_lng = S2.GetDistance(current_b.ToPoint(), lng_edge_a[j][0], lng_edge_a[j][1]);

                min_distance = new[] { min_distance, a_to_lat, b_to_lat, a_to_lng, b_to_lng }.Min();
            }
        }
        return(min_distance);
    }
Beispiel #3
0
    private static S1Angle BruteForceRectPointDistance(S2LatLngRect a, S2LatLng b)
    {
        if (a.Contains(b))
        {
            return(S1Angle.FromRadians(0));
        }

        S1Angle b_to_lo_lat = GetDistance(b, a.LatLo(), a.Lng);
        S1Angle b_to_hi_lat = GetDistance(b, a.LatHi(), a.Lng);
        S1Angle b_to_lo_lng = S2.GetDistance(b.ToPoint(), new S2LatLng(a.LatLo(), a.LngLo()).ToPoint(), new S2LatLng(a.LatHi(), a.LngLo()).ToPoint());
        S1Angle b_to_hi_lng = S2.GetDistance(b.ToPoint(), new S2LatLng(a.LatLo(), a.LngHi()).ToPoint(), new S2LatLng(a.LatHi(), a.LngHi()).ToPoint());

        return(new[] { b_to_lo_lat, b_to_hi_lat, b_to_lo_lng, b_to_hi_lng }.Min());
    }