Пример #1
0
    private static S2Point PerturbATowardsB(S2Point a, S2Point b)
    {
        var choice = S2Testing.Random.RandDouble();

        if (choice < 0.1)
        {
            return(a);
        }
        if (choice < 0.3)
        {
            // Return a point that is exactly proportional to A and that still
            // satisfies S2.IsUnitLength().
            for (; ;)
            {
                var b2 = (2 - a.Norm() + 5 * (S2Testing.Random.RandDouble() - 0.5) * S2.DoubleEpsilon) * a;
                if (b2 != a && b2.IsUnitLength())
                {
                    return(b2);
                }
            }
        }
        if (choice < 0.5)
        {
            // Return a point such that the distance squared to A will underflow.
            return(S2.InterpolateAtDistance(S1Angle.FromRadians(1e-300), a, b));
        }
        // Otherwise return a point whose distance from A is near S2Constants.DoubleEpsilon such
        // that the log of the pdf is uniformly distributed.
        double distance = S2.DoubleEpsilon * 1e-5 * Math.Pow(1e6, S2Testing.Random.RandDouble());

        return(S2.InterpolateAtDistance(S1Angle.FromRadians(distance), a, b));
    }
Пример #2
0
        public void Test_EdgeTrueCentroid_GreatCircles()
        {
            // Construct random great circles and divide them randomly into segments.
            // Then make sure that the centroid is approximately at the center of the
            // sphere.  Note that because of the way the centroid is computed, it does
            // not matter how we split the great circle into segments.
            //
            // Note that this is a direct test of the properties that the centroid
            // should have, rather than a test that it matches a particular formula.

            for (int iter = 0; iter < 100; ++iter)
            {
                // Choose a coordinate frame for the great circle.
                S2Point centroid = S2Point.Empty;
                S2Testing.GetRandomFrame(out var x, out var y, out _);

                S2Point v0 = x;
                for (double theta = 0; theta < S2.M_2_PI;
                     theta += Math.Pow(S2Testing.Random.RandDouble(), 10))
                {
                    S2Point v1 = Math.Cos(theta) * x + Math.Sin(theta) * y;
                    centroid += S2Centroid.TrueCentroid(v0, v1);
                    v0        = v1;
                }
                // Close the circle.
                centroid += S2Centroid.TrueCentroid(v0, x);
                Assert.True(centroid.Norm() <= 2e-14);
            }
        }
Пример #3
0
        public void Test_GetLengthAndCentroid_GreatCircles()
        {
            // Construct random great circles and divide them randomly into segments.
            // Then make sure that the length and centroid are correct.  Note that
            // because of the way the centroid is computed, it does not matter how
            // we split the great circle into segments.

            for (int iter = 0; iter < 100; ++iter)
            {
                // Choose a coordinate frame for the great circle.
                S2Testing.GetRandomFrame(out var x, out var y, out _);

                var    lineList = new List <S2Point>();
                double theta    = 0;
                while (theta < S2.M_2_PI)
                {
                    lineList.Add(Math.Cos(theta) * x + Math.Sin(theta) * y);
                    theta += S2Testing.Random.RandDouble();
                }
                // Close the circle.
                lineList.Add(lineList[0]);
                var     line   = lineList.ToArray();
                S1Angle length = S2PolylineMeasures.GetLength(line);
                Assert.True(Math.Abs(length.Radians - S2.M_2_PI) <= 2e-14);
                S2Point centroid = S2PolylineMeasures.GetCentroid(line);
                Assert.True(centroid.Norm() <= 2e-14);
            }
        }
Пример #4
0
        public void Test_EdgeTrueCentroid_SemiEquator()
        {
            // Test the centroid of polyline ABC that follows the equator and consists
            // of two 90 degree edges (i.e., C = -A).  The centroid (multiplied by
            // length) should point toward B and have a norm of 2.0.  (The centroid
            // itself has a norm of 2/Pi, and the total edge length is Pi.)
            S2Point a = new(0, -1, 0), b = new(1, 0, 0), c = new(0, 1, 0);
            S2Point centroid = S2Centroid.TrueCentroid(a, b) + S2Centroid.TrueCentroid(b, c);

            Assert.True(S2.ApproxEquals(b, centroid.Normalize()));
            Assert2.DoubleEqual(2.0, centroid.Norm());
        }