Example #1
0
    // This function is designed to choose line segment endpoints that are difficult
    // to handle correctly.  Given two adjacent cube vertices P and Q, it returns
    // either an edge midpoint, face midpoint, or corner vertex along the edge PQ
    // and then perturbs it slightly.  It also sometimes returns a random point from
    // anywhere on the sphere.
    private S2Point PerturbedCornerOrMidpoint(S2Point p, S2Point q)
    {
        S2Point a = (S2Testing.Random.Uniform(3) - 1) * p + (S2Testing.Random.Uniform(3) - 1) * q;

        if (S2Testing.Random.OneIn(10))
        {
            // This perturbation often has no effect except on coordinates that are
            // zero, in which case the perturbed value is so small that operations on
            // it often result in underflow.
            a += Math.Pow(1e-300, S2Testing.Random.RandDouble()) * S2Testing.RandomPoint();
        }
        else if (S2Testing.Random.OneIn(2))
        {
            // For coordinates near 1 (say > 0.5), this perturbation yields values
            // that are only a few representable values away from the initial value.
            a += 4 * S2.DoubleEpsilon * S2Testing.RandomPoint();
        }
        else
        {
            // A perturbation whose magnitude is in the range [1e-25, 1e-10].
            a += 1e-10 * Math.Pow(S2.DoubleError, S2Testing.Random.RandDouble()) * S2Testing.RandomPoint();
        }
        if (a.Norm2() < S2.DoubleMinNorm)
        {
            // If a.Norm2 is denormalized, Normalize() loses too much precision.
            return(PerturbedCornerOrMidpoint(p, q));
        }
        return(a);
    }