public void testNeighbors()
        {
            Trace.WriteLine("TestNeighbors");

            // Check the edge neighbors of face 1.
            int[] outFaces = { 5, 3, 2, 0 };

            var faceNbrs = S2CellId.FromFacePosLevel(1, 0, 0).GetEdgeNeighbors();

            for (var i = 0; i < 4; ++i)
            {
                Assert.True(faceNbrs[i].IsFace);
                JavaAssert.Equal(faceNbrs[i].Face, outFaces[i]);
            }

            // Check the vertex neighbors of the center of face 2 at level 5.
            var nbrs = new List <S2CellId>();

            S2CellId.FromPoint(new S2Point(0, 0, 1)).GetVertexNeighbors(5, nbrs);
            nbrs.Sort();
            for (var i = 0; i < 4; ++i)
            {
                JavaAssert.Equal(nbrs[i], S2CellId.FromFaceIj(
                                     2, (1 << 29) - (i < 2 ? 1 : 0), (1 << 29) - ((i == 0 || i == 3) ? 1 : 0)).ParentForLevel(5));
            }
            nbrs.Clear();

            // Check the vertex neighbors of the corner of faces 0, 4, and 5.
            var id = S2CellId.FromFacePosLevel(0, 0, S2CellId.MaxLevel);

            id.GetVertexNeighbors(0, nbrs);
            nbrs.Sort();

            JavaAssert.Equal(nbrs.Count, 3);
            JavaAssert.Equal(nbrs[0], S2CellId.FromFacePosLevel(0, 0, 0));
            JavaAssert.Equal(nbrs[1], S2CellId.FromFacePosLevel(4, 0, 0));
            JavaAssert.Equal(nbrs[2], S2CellId.FromFacePosLevel(5, 0, 0));

            // Check that GetAllNeighbors produces results that are consistent
            // with GetVertexNeighbors for a bunch of random cells.
            for (var i = 0; i < 1000; ++i)
            {
                var id1    = getRandomCellId();
                var toTest = id1;
                if (id1.IsLeaf)
                {
                    toTest = id1.Parent;
                }

                // TestAllNeighbors computes approximately 2**(2*(diff+1)) cell id1s,
                // so it's not reasonable to use large values of "diff".
                var maxDiff = Math.Min(6, S2CellId.MaxLevel - toTest.Level - 1);
                var level   = toTest.Level + random(maxDiff);
                testAllNeighbors(toTest, level);
            }
        }
        public void testCoverage()
        {
            Trace.WriteLine("TestCoverage");
            // Make sure that random points on the sphere can be represented to the
            // expected level of accuracy, which in the worst case is sqrt(2/3) times
            // the maximum arc length between the points on the sphere associated with
            // adjacent values of "i" or "j". (It is sqrt(2/3) rather than 1/2 because
            // the cells at the corners of each face are stretched -- they have 60 and
            // 120 degree angles.)

            var maxDist = 0.5 * S2Projections.MaxDiag.GetValue(S2CellId.MaxLevel);

            for (var i = 0; i < 1000000; ++i)
            {
                // randomPoint();
                var p = new S2Point(0.37861576725894824, 0.2772406863275093, 0.8830558887338725);
                var q = S2CellId.FromPoint(p).ToPointRaw();

                Assert.True(p.Angle(q) <= maxDist);
            }
        }