예제 #1
0
    // Checks that the error returned by S2EdgeDistances.GetUpdateMinDistanceMaxError() for
    // the distance "input" (measured in radians) corresponds to a distance error
    // of less than "max_error" (measured in radians).
    //
    // The reason for the awkward phraseology above is that the value returned by
    // GetUpdateMinDistanceMaxError() is not a distance; it represents an error in
    // the *squared* distance.
    private static void CheckUpdateMinDistanceMaxError(double actual, double max_error)
    {
        S1ChordAngle ca    = new(S1Angle.FromRadians(actual));
        S1Angle      bound = ca.PlusError(S2.GetUpdateMinDistanceMaxError(ca)).ToAngle();

        Assert.True(bound.Radians - actual <= max_error);
    }
예제 #2
0
    public void Test_S2_GetUpdateMinInteriorDistanceMaxError()
    {
        // Check that the error bound returned by
        // GetUpdateMinInteriorDistanceMaxError() is large enough.
        for (int iter = 0; iter < 10000; ++iter)
        {
            S2Point a0         = S2Testing.RandomPoint();
            var     lenRadians = Math.PI * Math.Pow(1e-20, S2Testing.Random.RandDouble());
            S1Angle len        = S1Angle.FromRadians(lenRadians);
            if (S2Testing.Random.OneIn(4))
            {
                len = S1Angle.FromRadians(S2.M_PI) - len;
            }
            S2Point a1 = S2.GetPointOnLine(a0, S2Testing.RandomPoint(), len);

            // TODO(ericv): The error bound holds for antipodal points, but the S2
            // predicates used to test the error do not support antipodal points yet.
            if (a1 == -a0)
            {
                continue;
            }
            S2Point n        = S2.RobustCrossProd(a0, a1).Normalize();
            double  f        = Math.Pow(1e-20, S2Testing.Random.RandDouble());
            S2Point a        = ((1 - f) * a0 + f * a1).Normalize();
            var     rRadians = S2.M_PI_2 * Math.Pow(1e-20, S2Testing.Random.RandDouble());
            S1Angle r        = S1Angle.FromRadians(rRadians);
            if (S2Testing.Random.OneIn(2))
            {
                r = S1Angle.FromRadians(S2.M_PI_2) - r;
            }
            S2Point      x        = S2.GetPointOnLine(a, n, r);
            S1ChordAngle min_dist = S1ChordAngle.Infinity;
            if (!S2.UpdateMinInteriorDistance(x, a0, a1, ref min_dist))
            {
                --iter; continue;
            }
            double error = S2.GetUpdateMinDistanceMaxError(min_dist);
            Assert.True(S2Pred.CompareEdgeDistance(x, a0, a1, min_dist.PlusError(error)) <= 0);
            Assert.True(S2Pred.CompareEdgeDistance(x, a0, a1, min_dist.PlusError(-error)) >= 0);
        }
    }