Example #1
0
    public void Test_S1ChordAngle_ArithmeticPrecision()
    {
        // Verifies that S1ChordAngle is capable of adding and subtracting angles
        // extremely accurately up to Pi/2 radians.  (Accuracy continues to be good
        // well beyond this value but degrades as angles approach Pi.)
        S1ChordAngle kEps        = S1ChordAngle.FromRadians(1e-15);
        S1ChordAngle k90         = S1ChordAngle.Right;
        S1ChordAngle k90MinusEps = k90 - kEps;
        S1ChordAngle k90PlusEps  = k90 + kEps;
        double       kMaxError   = 2 * S2.DoubleEpsilon;

        Assert2.Near(k90MinusEps.Radians(), S2.M_PI_2 - kEps.Radians(), kMaxError);
        Assert2.Near(k90PlusEps.Radians(), S2.M_PI_2 + kEps.Radians(), kMaxError);
        Assert2.Near((k90 - k90MinusEps).Radians(), kEps.Radians(), kMaxError);
        Assert2.Near((k90PlusEps - k90).Radians(), kEps.Radians(), kMaxError);
        Assert2.Near((k90MinusEps + kEps).Radians(), S2.M_PI_2, kMaxError);
    }
Example #2
0
    private static void CheckMaxDistance(S2Point x, S2Point a, S2Point b, double distance_radians)
    {
        x = x.Normalize();
        a = a.Normalize();
        b = b.Normalize();

        S1ChordAngle max_distance = S1ChordAngle.Straight;

        Assert.False(S2.UpdateMaxDistance(x, a, b, ref max_distance));
        max_distance = S1ChordAngle.Negative;
        Assert.True(S2.UpdateMaxDistance(x, a, b, ref max_distance));
        Assert2.Near(distance_radians, max_distance.Radians(), S2.DoubleError);
    }
Example #3
0
    // Given two edges a0a1 and b0b1, check that the maximum distance between them
    // is "distance_radians".  Parameters are passed by value so that this
    // function can normalize them.
    private static void CheckEdgePairMaxDistance(S2Point a0, S2Point a1, S2Point b0, S2Point b1, double distance_radians)
    {
        a0 = a0.Normalize();
        a1 = a1.Normalize();
        b0 = b0.Normalize();
        b1 = b1.Normalize();

        S1ChordAngle max_distance = S1ChordAngle.Straight;

        Assert.False(S2.UpdateEdgePairMaxDistance(a0, a1, b0, b1, ref max_distance));
        max_distance = S1ChordAngle.Negative;
        Assert.True(S2.UpdateEdgePairMaxDistance(a0, a1, b0, b1, ref max_distance));
        Assert2.Near(distance_radians, max_distance.Radians(), S2.DoubleError);
    }
Example #4
0
        public void Test_S2Cell_GetMaxDistanceToEdge()
        {
            // Test an edge for which its antipode crosses the cell. Validates both the
            // standard and brute force implementations for this case.
            S2Cell  cell = S2Cell.FromFacePosLevel(0, 0, 20);
            S2Point a    = -S2.Interpolate(2.0, cell.Center(), cell.Vertex(0));
            S2Point b    = -S2.Interpolate(2.0, cell.Center(), cell.Vertex(2));

            S1ChordAngle actual   = cell.MaxDistance(a, b);
            S1ChordAngle expected = GetMaxDistanceToEdgeBruteForce(cell, a, b);

            Assert2.Near(expected.Radians(), S1ChordAngle.Straight.Radians(), S2.DoubleError);
            Assert2.Near(actual.Radians(), S1ChordAngle.Straight.Radians(), S2.DoubleError);
        }
Example #5
0
        public void Test_S2Cell_GetMaxDistanceToCell()
        {
            for (int i = 0; i < 1000; i++)
            {
                S2Cell   cell                = new(S2Testing.GetRandomCellId());
                S2Cell   test_cell           = new(S2Testing.GetRandomCellId());
                S2CellId antipodal_leaf_id   = new(-test_cell.Center());
                S2Cell   antipodal_test_cell = new(antipodal_leaf_id.Parent(test_cell.Level));

                S1ChordAngle dist_from_min = S1ChordAngle.Straight -
                                             cell.Distance(antipodal_test_cell);
                S1ChordAngle dist_from_max = cell.MaxDistance(test_cell);
                Assert2.Near(dist_from_min.Radians(), dist_from_max.Radians(), 1e-8);
            }
        }
Example #6
0
    // Given two edges a0a1 and b0b1, check that the minimum distance between them
    // is "distance_radians", and that GetEdgePairClosestPoints() returns
    // "expected_a" and "expected_b" as the points that achieve this distance.
    // S2Point.Empty may be passed for "expected_a" or "expected_b" to indicate
    // that both endpoints of the corresponding edge are equally distant, and
    // therefore either one might be returned.
    //
    // Parameters are passed by value so that this function can normalize them.
    private static void CheckEdgePairMinDistance(S2Point a0, S2Point a1, S2Point b0, S2Point b1, double distance_radians, S2Point expected_a, S2Point expected_b)
    {
        a0         = a0.Normalize();
        a1         = a1.Normalize();
        b0         = b0.Normalize();
        b1         = b1.Normalize();
        expected_a = expected_a.Normalize();
        expected_b = expected_b.Normalize();
        var     closest  = S2.GetEdgePairClosestPoints(a0, a1, b0, b1);
        S2Point actual_a = closest.Item1;
        S2Point actual_b = closest.Item2;

        if (expected_a == S2Point.Empty)
        {
            // This special value says that the result should be a0 or a1.
            Assert.True(actual_a == a0 || actual_a == a1);
        }
        else
        {
            Assert.True(S2.ApproxEquals(expected_a, actual_a));
        }
        if (expected_b == S2Point.Empty)
        {
            // This special value says that the result should be b0 or b1.
            Assert.True(actual_b == b0 || actual_b == b1);
        }
        else
        {
            Assert.True(S2.ApproxEquals(expected_b, actual_b));
        }
        S1ChordAngle min_distance = S1ChordAngle.Zero;

        Assert.False(S2.UpdateEdgePairMinDistance(a0, a1, b0, b1, ref min_distance));
        min_distance = S1ChordAngle.Infinity;
        Assert.True(S2.UpdateEdgePairMinDistance(a0, a1, b0, b1, ref min_distance));
        Assert2.Near(distance_radians, min_distance.Radians(), S2.DoubleError);
    }