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); } }