public void Test_S2ClosestEdgeQuery_TrueDistanceLessThanS1ChordAngleDistance() { // Tests that IsConservativeDistanceLessOrEqual returns points where the // true distance is slightly less than the one computed by S1ChordAngle. // // The points below had the worst error from among 100,000 random pairs. S2Point p0 = new(0.78516762584829192, -0.50200400690845970, -0.36263449417782678); S2Point p1 = new(0.78563011732429433, -0.50187655940493503, -0.36180828883938054); // The S1ChordAngle distance is ~4 ulps greater than the true distance. Distance dist1 = new(p0, p1); var limit = dist1.Predecessor().Predecessor().Predecessor().Predecessor(); Assert.True(S2Pred.CompareDistance(p0, p1, limit) < 0); // Verify that IsConservativeDistanceLessOrEqual() still returns "p1". S2Point[] index_points = new[] { p0 }; MutableS2ShapeIndex index = new(); index.Add(new S2PointVectorShape(index_points)); S2ClosestEdgeQuery query = new(index); S2ClosestEdgeQuery.PointTarget target1 = new(p1); Assert.False(query.IsDistanceLess(target1, limit)); Assert.False(query.IsDistanceLessOrEqual(target1, limit)); Assert.True(query.IsConservativeDistanceLessOrEqual(target1, limit)); }
public void Test_S1ChordAngle_GetS2PointConstructorMaxError() { // Check that the error bound returned by GetS2PointConstructorMaxError() is // large enough. for (var iter = 0; iter < 100000; ++iter) { S2Testing.Random.Reset(iter); // Easier to reproduce a specific case. var x = S2Testing.RandomPoint(); var y = S2Testing.RandomPoint(); if (S2Testing.Random.OneIn(10)) { // Occasionally test a point pair that is nearly identical or antipodal. var r = S1Angle.FromRadians(S2.DoubleError * S2Testing.Random.RandDouble()); y = S2.GetPointOnLine(x, y, r); if (S2Testing.Random.OneIn(2)) { y = -y; } } S1ChordAngle dist = new(x, y); var error = dist.GetS2PointConstructorMaxError(); var er1 = S2Pred.CompareDistance(x, y, dist.PlusError(error)); if (er1 > 0) { } Assert.True(er1 <= 0); var er2 = S2Pred.CompareDistance(x, y, dist.PlusError(-error)); if (er2 < 0) { } Assert.True(er2 >= 0); } }
public void Test_S2ClosestEdgeQuery_IsConservativeDistanceLessOrEqual() { // Test int num_tested = 0; int num_conservative_needed = 0; for (int iter = 0; iter < 1000; ++iter) { S2Testing.Random.Reset(iter + 1); // Easier to reproduce a specific case. S2Point x = S2Testing.RandomPoint(); S2Point dir = S2Testing.RandomPoint(); S1Angle r = S1Angle.FromRadians(Math.PI * Math.Pow(1e-30, S2Testing.Random.RandDouble())); S2Point y = S2.InterpolateAtDistance(r, x, dir); Distance limit = new(r); if (S2Pred.CompareDistance(x, y, limit) <= 0) { MutableS2ShapeIndex index = new(); index.Add(new S2PointVectorShape(new S2Point[] { x })); S2ClosestEdgeQuery query = new(index); S2ClosestEdgeQuery.PointTarget target = new(y); Assert.True(query.IsConservativeDistanceLessOrEqual(target, limit)); ++num_tested; if (!query.IsDistanceLess(target, limit)) { ++num_conservative_needed; } } } // Verify that in most test cases, the distance between the target points // was close to the desired value. Also verify that at least in some test // cases, the conservative distance test was actually necessary. Assert.True(num_tested >= 300); Assert.True(num_tested <= 700); Assert.True(num_conservative_needed >= 25); }