예제 #1
0
    public void Test_LoopTestBase_GetCurvature()
    {
        Assert.Equal(-S2.M_2_PI, S2.GetCurvature(full_));

        Assert.Equal(S2.M_2_PI, S2.GetCurvature(v_loop_));
        CheckCurvatureInvariants(v_loop_);

        // This curvature should be computed exactly.
        Assert.Equal(0, S2.GetCurvature(north_hemi3_));
        CheckCurvatureInvariants(north_hemi3_);

        Assert2.Near(0, S2.GetCurvature(west_hemi_), 1e-15);
        CheckCurvatureInvariants(west_hemi_);

        // We don't have an easy way to estimate the curvature of these loops, but
        // we can still check that the expected invariants hold.
        CheckCurvatureInvariants(candy_cane_);
        CheckCurvatureInvariants(three_leaf_clover_);

        Assert2.DoubleEqual(S2.M_2_PI, S2.GetCurvature(line_triangle_));
        CheckCurvatureInvariants(line_triangle_);

        Assert2.DoubleEqual(S2.M_2_PI, S2.GetCurvature(skinny_chevron_));
        CheckCurvatureInvariants(skinny_chevron_);

        // Build a narrow spiral loop starting at the north pole.  This is designed
        // to test that the error in GetCurvature is linear in the number of
        // vertices even when the partial sum of the curvatures gets very large.
        // The spiral consists of two "arms" defining opposite sides of the loop.
        // This is a pathological loop that contains many long parallel edges.
        int             kArmPoints = 10000; // Number of vertices in each "arm"
        double          kArmRadius = 0.01;  // Radius of spiral.
        S2PointLoopSpan spiral     = new(2 * kArmPoints);

        spiral[kArmPoints] = new S2Point(0, 0, 1);
        for (int i = 0; i < kArmPoints; ++i)
        {
            double angle = (S2.M_2_PI / 3) * i;
            double x     = Math.Cos(angle);
            double y     = Math.Sin(angle);
            double r1    = i * kArmRadius / kArmPoints;
            double r2    = (i + 1.5) * kArmRadius / kArmPoints;
            spiral[kArmPoints - i - 1] = new S2Point(r1 * x, r1 * y, 1).Normalize();
            spiral[kArmPoints + i]     = new S2Point(r2 * x, r2 * y, 1).Normalize();
        }

        // Check that GetCurvature() is consistent with GetArea() to within the
        // error bound of the former.  We actually use a tiny fraction of the
        // worst-case error bound, since the worst case only happens when all the
        // roundoff errors happen in the same direction and this test is not
        // designed to achieve that.  The error in GetArea() can be ignored for the
        // purposes of this test since it is generally much smaller.
        Assert2.Near(
            S2.M_2_PI - S2.GetArea(spiral),
            S2.GetCurvature(spiral),
            0.01 * S2.GetCurvatureMaxError(spiral));
    }
예제 #2
0
    private static void TestAreaConsistentWithCurvature(S2PointLoopSpan loop)
    {
        // Check that the area computed using GetArea() is consistent with the loop
        // curvature.  According to the Gauss-Bonnet theorem, the area of the loop
        // equals 2*Pi minus its curvature.
        double area       = S2.GetArea(loop);
        double gauss_area = S2.M_2_PI - S2.GetCurvature(loop);

        // The error bound below is sufficient for current tests but not guaranteed.
        _ = loop.ToDebugString();
        Assert.True(Math.Abs(area - gauss_area) <= 1e-14);
    }
예제 #3
0
    // Check that the curvature is *identical* when the vertex order is
    // rotated, and that the sign is inverted when the vertices are reversed.
    private static void CheckCurvatureInvariants(S2PointLoopSpan loop_in)
    {
        S2.LoopOrder order_in = S2.GetCanonicalLoopOrder(loop_in);
        var          loop     = loop_in.ToList();
        double       expected = S2.GetCurvature(loop);

        for (int i = 0; i < loop.Count; ++i)
        {
            loop.Reverse();
            Assert.Equal((expected == S2.M_2_PI) ? expected : -expected,
                         S2.GetCurvature(loop));
            ExpectSameOrder(loop_in, order_in, loop, S2.GetCanonicalLoopOrder(loop));
            loop.Reverse();
            loop.RotateInPlace(1);
            Assert.Equal(expected, S2.GetCurvature(loop));
            ExpectSameOrder(loop_in, order_in, loop, S2.GetCanonicalLoopOrder(loop));
        }
    }