public void testContainment()
        {
            Trace.WriteLine("TestContainment");
            IDictionary <S2CellId, S2CellId> parentMap = new Dictionary <S2CellId, S2CellId>();
            var cells = new List <S2CellId>();

            for (var face = 0; face < 6; ++face)
            {
                expandCell(S2CellId.FromFacePosLevel(face, 0, 0), cells, parentMap);
            }
            for (var i = 0; i < cells.Count; ++i)
            {
                for (var j = 0; j < cells.Count; ++j)
                {
                    var contained = true;
                    for (var id = cells[j]; id != cells[i]; id = parentMap[id])
                    {
                        if (!parentMap.ContainsKey(id))
                        {
                            contained = false;
                            break;
                        }
                    }
                    JavaAssert.Equal(cells[i].Contains(cells[j]), contained);
                    JavaAssert.Equal(cells[j] >= cells[i].RangeMin &&
                                     cells[j] <= cells[i].RangeMax, contained);
                    JavaAssert.Equal(cells[i].Intersects(cells[j]),
                                     cells[i].Contains(cells[j]) || cells[j].Contains(cells[i]));
                }
            }
        }
        private void expandCell(
            S2CellId parent, List <S2CellId> cells, IDictionary <S2CellId, S2CellId> parentMap)
        {
            cells.Add(parent);
            if (parent.Level == kMaxExpandLevel)
            {
                return;
            }
            var i           = 0;
            var j           = 0;
            int?orientation = 0;
            var face        = parent.ToFaceIjOrientation(ref i, ref j, ref orientation);

            JavaAssert.Equal(face, parent.Face);

            var pos = 0;

            for (var child = parent.ChildBegin; !child.Equals(parent.ChildEnd);
                 child = child.Next)
            {
                // Do some basic checks on the children
                JavaAssert.Equal(child.Level, parent.Level + 1);
                Assert.True(!child.IsLeaf);
                int?childOrientation = 0;
                JavaAssert.Equal(child.ToFaceIjOrientation(ref i, ref j, ref childOrientation), face);
                JavaAssert.Equal(
                    childOrientation.Value, orientation.Value ^ S2.PosToOrientation(pos));

                parentMap.Add(child, parent);
                expandCell(child, cells, parentMap);
                ++pos;
            }
        }
        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 S2CellIdTestBasic()
        {
            Trace.WriteLine("TestBasic");
            // Check default constructor.
            var id = new S2CellId();

            //JavaAssert.Equal(id.id(), 0);
            //Assert.True(!id.isValid());

            // Check basic accessor methods.
            id = S2CellId.FromFacePosLevel(3, 0x12345678, S2CellId.MaxLevel - 4);
            //Assert.True(id.isValid());
            //JavaAssert.Equal(id.face(), 3);
            // JavaAssert.Equal(id.pos(), 0x12345700);
            //JavaAssert.Equal(id.level(), S2CellId.MAX_LEVEL - 4);
            //Assert.True(!id.isLeaf());

            //// Check face definitions
            //JavaAssert.Equal(getCellId(0, 0).face(), 0);
            //JavaAssert.Equal(getCellId(0, 90).face(), 1);
            //JavaAssert.Equal(getCellId(90, 0).face(), 2);
            //JavaAssert.Equal(getCellId(0, 180).face(), 3);
            //JavaAssert.Equal(getCellId(0, -90).face(), 4);
            //JavaAssert.Equal(getCellId(-90, 0).face(), 5);

            //// Check parent/child relationships.
            //JavaAssert.Equal(id.childBegin(id.level() + 2).pos(), 0x12345610);
            //JavaAssert.Equal(id.childBegin().pos(), 0x12345640);
            //JavaAssert.Equal(id.parent().pos(), 0x12345400);
            //JavaAssert.Equal(id.parent(id.level() - 2).pos(), 0x12345000);

            //// Check ordering of children relative to parents.
            //Assert.True(id.childBegin().lessThan(id));
            //var childEnd = id.childEnd();
            //var childId = childEnd.id();
            //var id1 = id.id();

            //Assert.True(id.childEnd().greaterThan(id));
            //JavaAssert.Equal(id.childBegin().next().next().next().next(), id.childEnd());
            //JavaAssert.Equal(id.childBegin(S2CellId.MAX_LEVEL), id.rangeMin());
            //JavaAssert.Equal(id.childEnd(S2CellId.MAX_LEVEL), id.rangeMax().next());

            // Check wrapping from beginning of Hilbert curve to end and vice versa.
            // JavaAssert.Equal(S2CellId.begin(0).prevWrap(), S2CellId.end(0).prev());

            JavaAssert.Equal(S2CellId.Begin(S2CellId.MaxLevel).PreviousWithWrap,
                             S2CellId.FromFacePosLevel(5, ~0UL >> S2CellId.FaceBits, S2CellId.MaxLevel));

            JavaAssert.Equal(S2CellId.End(4).Previous.NextWithWrap, S2CellId.Begin(4));
            JavaAssert.Equal(S2CellId.End(S2CellId.MaxLevel).Previous.NextWithWrap,
                             S2CellId.FromFacePosLevel(0, 0, S2CellId.MaxLevel));

            // Check that cells are represented by the position of their center
            // along the Hilbert curve.
            JavaAssert.Equal(id.RangeMin.Id + id.RangeMax.Id, 2 * id.Id);
        }
Example #5
0
        /**
         * Test all of the interval operations on the given pair of intervals.
         * "expected_relation" is a sequence of "T" and "F" characters corresponding
         * to the expected results of contains(), interiorContains(), Intersects(),
         * and InteriorIntersects() respectively.
         */

        private void testIntervalOps(R1Interval x, R1Interval y, String expectedRelation)
        {
            JavaAssert.Equal(x.Contains(y), expectedRelation[0] == 'T');
            JavaAssert.Equal(x.InteriorContains(y), expectedRelation[1] == 'T');
            JavaAssert.Equal(x.Intersects(y), expectedRelation[2] == 'T');
            JavaAssert.Equal(x.InteriorIntersects(y), expectedRelation[3] == 'T');

            JavaAssert.Equal(x.Contains(y), x.Union(y).Equals(x));
            JavaAssert.Equal(x.Intersects(y), !x.Intersection(y).IsEmpty);
        }
        public void testFaces()
        {
            IDictionary <S2Point, int> edgeCounts   = new Dictionary <S2Point, int>();
            IDictionary <S2Point, int> vertexCounts = new Dictionary <S2Point, int>();

            for (var face = 0; face < 6; ++face)
            {
                var id   = S2CellId.FromFacePosLevel(face, 0, 0);
                var cell = new S2Cell(id);
                JavaAssert.Equal(cell.Id, id);
                JavaAssert.Equal(cell.Face, face);
                JavaAssert.Equal(cell.Level, 0);
                // Top-level faces have alternating orientations to get RHS coordinates.
                JavaAssert.Equal(cell.Orientation, face & S2.SwapMask);
                Assert.True(!cell.IsLeaf);
                for (var k = 0; k < 4; ++k)
                {
                    if (edgeCounts.ContainsKey(cell.GetEdgeRaw(k)))
                    {
                        edgeCounts[cell.GetEdgeRaw(k)] = edgeCounts[cell
                                                                    .GetEdgeRaw(k)] + 1;
                    }
                    else
                    {
                        edgeCounts[cell.GetEdgeRaw(k)] = 1;
                    }

                    if (vertexCounts.ContainsKey(cell.GetVertexRaw(k)))
                    {
                        vertexCounts[cell.GetVertexRaw(k)] = vertexCounts[cell
                                                                          .GetVertexRaw(k)] + 1;
                    }
                    else
                    {
                        vertexCounts[cell.GetVertexRaw(k)] = 1;
                    }
                    assertDoubleNear(cell.GetVertexRaw(k).DotProd(cell.GetEdgeRaw(k)), 0);
                    assertDoubleNear(cell.GetVertexRaw((k + 1) & 3).DotProd(
                                         cell.GetEdgeRaw(k)), 0);
                    assertDoubleNear(S2Point.Normalize(
                                         S2Point.CrossProd(cell.GetVertexRaw(k), cell
                                                           .GetVertexRaw((k + 1) & 3))).DotProd(cell.GetEdge(k)), 1.0);
                }
            }
            // Check that edges have multiplicity 2 and vertices have multiplicity 3.
            foreach (var i in edgeCounts.Values)
            {
                JavaAssert.Equal(i, 2);
            }
            foreach (var i in vertexCounts.Values)
            {
                JavaAssert.Equal(i, 3);
            }
        }
 public void testInverses()
 {
     Trace.WriteLine("TestInverses");
     // Check the conversion of random leaf cells to S2LatLngs and back.
     for (var i = 0; i < 200000; ++i)
     {
         var id = getRandomCellId(S2CellId.MaxLevel);
         Assert.True(id.IsLeaf && id.Level == S2CellId.MaxLevel);
         var center = id.ToLatLng();
         JavaAssert.Equal(S2CellId.FromLatLng(center).Id, id.Id);
     }
 }
        public void testTokens()
        {
            Trace.WriteLine("TestTokens");

            // Test random cell ids at all levels.
            for (var i = 0; i < 10000; ++i)
            {
                var id = getRandomCellId();
                if (!id.IsValid)
                {
                    continue;
                }
                var token = id.ToToken();
                Assert.True(token.Length <= 16);
                JavaAssert.Equal(S2CellId.FromToken(token), id);
            }
            // Check that invalid cell ids can be encoded.
            var token1 = S2CellId.None.ToToken();

            JavaAssert.Equal(S2CellId.FromToken(token1), S2CellId.None);
        }
        public void S1AngleBasicTest()
        {
            // Check that the conversion between Pi radians and 180 degrees is exact.
            JavaAssert.Equal(S1Angle.FromRadians(Math.PI).Radians, Math.PI);
            JavaAssert.Equal(S1Angle.FromRadians(Math.PI).Degrees, 180.0);
            JavaAssert.Equal(S1Angle.FromDegrees(180).Radians, Math.PI);
            JavaAssert.Equal(S1Angle.FromDegrees(180).Degrees, 180.0);

            JavaAssert.Equal(S1Angle.FromRadians(Math.PI / 2).Degrees, 90.0);

            // Check negative angles.
            JavaAssert.Equal(S1Angle.FromRadians(-Math.PI / 2).Degrees, -90.0);
            JavaAssert.Equal(S1Angle.FromDegrees(-45).Radians, -Math.PI / 4);

            // Check that E5/E6/E7 representations work as expected.
            JavaAssert.Equal(S1Angle.E5(2000000), S1Angle.FromDegrees(20));
            JavaAssert.Equal(S1Angle.E6(-60000000), S1Angle.FromDegrees(-60));
            JavaAssert.Equal(S1Angle.E7(750000000), S1Angle.FromDegrees(75));
            JavaAssert.Equal(S1Angle.FromDegrees(12.34567).E5(), 1234567);
            JavaAssert.Equal(S1Angle.FromDegrees(12.345678).E6(), 12345678);
            JavaAssert.Equal(S1Angle.FromDegrees(-12.3456789).E7(), -123456789);
        }
Example #10
0
        public void testCells()
        {
            // For each cube face, we construct some cells on
            // that face and some caps whose positions are relative to that face,
            // and then check for the expected intersection/containment results.

            // The distance from the center of a face to one of its vertices.
            var kFaceRadius = Math.Atan(S2.Sqrt2);

            for (var face = 0; face < 6; ++face)
            {
                // The cell consisting of the entire face.
                var rootCell = S2Cell.FromFacePosLevel(face, (byte)0, 0);

                // A leaf cell at the midpoint of the v=1 edge.
                var edgeCell = new S2Cell(S2Projections.FaceUvToXyz(face, 0, 1 - EPS));

                // A leaf cell at the u=1, v=1 corner.
                var cornerCell = new S2Cell(S2Projections.FaceUvToXyz(face, 1 - EPS, 1 - EPS));

                // Quick check for full and empty caps.
                Assert.True(S2Cap.Full.Contains(rootCell));
                Assert.True(!S2Cap.Empty.MayIntersect(rootCell));

                // Check intersections with the bounding caps of the leaf cells that are
                // adjacent to 'corner_cell' along the Hilbert curve. Because this corner
                // is at (u=1,v=1), the curve stays locally within the same cube face.
                var first = cornerCell.Id.Previous.Previous.Previous;
                var last  = cornerCell.Id.Next.Next.Next.Next;
                for (var id = first; id < last; id = id.Next)
                {
                    var cell = new S2Cell(id);
                    JavaAssert.Equal(cell.CapBound.Contains(cornerCell), id.Equals(cornerCell.Id));
                    JavaAssert.Equal(
                        cell.CapBound.MayIntersect(cornerCell), id.Parent.Contains(cornerCell.Id));
                }

                var antiFace = (face + 3) % 6; // Opposite face.
                for (var capFace = 0; capFace < 6; ++capFace)
                {
                    // A cap that barely contains all of 'cap_face'.
                    var center   = S2Projections.GetNorm(capFace);
                    var covering = S2Cap.FromAxisAngle(center, S1Angle.FromRadians(kFaceRadius + EPS));
                    JavaAssert.Equal(covering.Contains(rootCell), capFace == face);
                    JavaAssert.Equal(covering.MayIntersect(rootCell), capFace != antiFace);
                    JavaAssert.Equal(covering.Contains(edgeCell), center.DotProd(edgeCell.Center) > 0.1);
                    JavaAssert.Equal(covering.Contains(edgeCell), covering.MayIntersect(edgeCell));
                    JavaAssert.Equal(covering.Contains(cornerCell), capFace == face);
                    JavaAssert.Equal(
                        covering.MayIntersect(cornerCell), center.DotProd(cornerCell.Center) > 0);

                    // A cap that barely intersects the edges of 'cap_face'.
                    var bulging = S2Cap.FromAxisAngle(center, S1Angle.FromRadians(S2.PiOver4 + EPS));
                    Assert.True(!bulging.Contains(rootCell));
                    JavaAssert.Equal(bulging.MayIntersect(rootCell), capFace != antiFace);
                    JavaAssert.Equal(bulging.Contains(edgeCell), capFace == face);
                    JavaAssert.Equal(bulging.MayIntersect(edgeCell), center.DotProd(edgeCell.Center) > 0.1);
                    Assert.True(!bulging.Contains(cornerCell));
                    Assert.True(!bulging.MayIntersect(cornerCell));

                    // A singleton cap.
                    var singleton = S2Cap.FromAxisAngle(center, S1Angle.FromRadians(0));
                    JavaAssert.Equal(singleton.MayIntersect(rootCell), capFace == face);
                    Assert.True(!singleton.MayIntersect(edgeCell));
                    Assert.True(!singleton.MayIntersect(cornerCell));
                }
            }
        }
Example #11
0
        public void S2CapBasicTest()
        {
            // Test basic properties of empty and full caps.
            var empty = S2Cap.Empty;
            var full  = S2Cap.Full;

            Assert.True(empty.IsValid);
            Assert.True(empty.IsEmpty);
            Assert.True(empty.Complement.IsFull);
            Assert.True(full.IsValid);
            Assert.True(full.IsFull);
            Assert.True(full.Complement.IsEmpty);
            JavaAssert.Equal(full.Height, 2.0);
            assertDoubleNear(full.Angle.Degrees, 180);

            // Containment and intersection of empty and full caps.
            Assert.True(empty.Contains(empty));
            Assert.True(full.Contains(empty));
            Assert.True(full.Contains(full));
            Assert.True(!empty.InteriorIntersects(empty));
            Assert.True(full.InteriorIntersects(full));
            Assert.True(!full.InteriorIntersects(empty));

            // Singleton cap containing the x-axis.
            var xaxis = S2Cap.FromAxisHeight(new S2Point(1, 0, 0), 0);

            Assert.True(xaxis.Contains(new S2Point(1, 0, 0)));
            Assert.True(!xaxis.Contains(new S2Point(1, 1e-20, 0)));
            JavaAssert.Equal(xaxis.Angle.Radians, 0.0);

            // Singleton cap containing the y-axis.
            var yaxis = S2Cap.FromAxisAngle(new S2Point(0, 1, 0), S1Angle.FromRadians(0));

            Assert.True(!yaxis.Contains(xaxis.Axis));
            JavaAssert.Equal(xaxis.Height, 0.0);

            // Check that the complement of a singleton cap is the full cap.
            var xcomp = xaxis.Complement;

            Assert.True(xcomp.IsValid);
            Assert.True(xcomp.IsFull);
            Assert.True(xcomp.Contains(xaxis.Axis));

            // Check that the complement of the complement is *not* the original.
            Assert.True(xcomp.Complement.IsValid);
            Assert.True(xcomp.Complement.IsEmpty);
            Assert.True(!xcomp.Complement.Contains(xaxis.Axis));

            // Check that very small caps can be represented accurately.
            // Here "kTinyRad" is small enough that unit vectors perturbed by this
            // amount along a tangent do not need to be renormalized.
            var kTinyRad = 1e-10;
            var tiny     =
                S2Cap.FromAxisAngle(S2Point.Normalize(new S2Point(1, 2, 3)), S1Angle.FromRadians(kTinyRad));
            var tangent = S2Point.Normalize(S2Point.CrossProd(tiny.Axis, new S2Point(3, 2, 1)));

            Assert.True(tiny.Contains(tiny.Axis + (tangent * 0.99 * kTinyRad)));
            Assert.True(!tiny.Contains(tiny.Axis + (tangent * 1.01 * kTinyRad)));

            // Basic tests on a hemispherical cap.
            var hemi = S2Cap.FromAxisHeight(S2Point.Normalize(new S2Point(1, 0, 1)), 1);

            JavaAssert.Equal(hemi.Complement.Axis, -hemi.Axis);
            JavaAssert.Equal(hemi.Complement.Height, 1.0);
            Assert.True(hemi.Contains(new S2Point(1, 0, 0)));
            Assert.True(!hemi.Complement.Contains(new S2Point(1, 0, 0)));
            Assert.True(hemi.Contains(S2Point.Normalize(new S2Point(1, 0, -(1 - EPS)))));
            Assert.True(!hemi.InteriorContains(S2Point.Normalize(new S2Point(1, 0, -(1 + EPS)))));

            // A concave cap.
            var concave = S2Cap.FromAxisAngle(getLatLngPoint(80, 10), S1Angle.FromDegrees(150));

            Assert.True(concave.Contains(getLatLngPoint(-70 * (1 - EPS), 10)));
            Assert.True(!concave.Contains(getLatLngPoint(-70 * (1 + EPS), 10)));
            Assert.True(concave.Contains(getLatLngPoint(-50 * (1 - EPS), -170)));
            Assert.True(!concave.Contains(getLatLngPoint(-50 * (1 + EPS), -170)));

            // Cap containment tests.
            Assert.True(!empty.Contains(xaxis));
            Assert.True(!empty.InteriorIntersects(xaxis));
            Assert.True(full.Contains(xaxis));
            Assert.True(full.InteriorIntersects(xaxis));
            Assert.True(!xaxis.Contains(full));
            Assert.True(!xaxis.InteriorIntersects(full));
            Assert.True(xaxis.Contains(xaxis));
            Assert.True(!xaxis.InteriorIntersects(xaxis));
            Assert.True(xaxis.Contains(empty));
            Assert.True(!xaxis.InteriorIntersects(empty));
            Assert.True(hemi.Contains(tiny));
            Assert.True(hemi.Contains(
                            S2Cap.FromAxisAngle(new S2Point(1, 0, 0), S1Angle.FromRadians(S2.PiOver4 - EPS))));
            Assert.True(!hemi.Contains(
                            S2Cap.FromAxisAngle(new S2Point(1, 0, 0), S1Angle.FromRadians(S2.PiOver4 + EPS))));
            Assert.True(concave.Contains(hemi));
            Assert.True(concave.InteriorIntersects(hemi.Complement));
            Assert.True(!concave.Contains(S2Cap.FromAxisHeight(-concave.Axis, 0.1)));
        }
 protected static void assertEquals(object actual, object expected)
 {
     JavaAssert.Equal(actual, expected);
 }
 public void testToToken()
 {
     JavaAssert.Equal("000000000000010a", new S2CellId(266).ToToken());
     JavaAssert.Equal("80855c", new S2CellId(unchecked ((ulong)-9185834709882503168L)).ToToken());
 }
        public void testSubdivide(S2Cell cell)
        {
            gatherStats(cell);
            if (cell.IsLeaf)
            {
                return;
            }

            var children = new S2Cell[4];

            for (var i = 0; i < children.Length; ++i)
            {
                children[i] = new S2Cell();
            }
            Assert.True(cell.Subdivide(children));
            var    childId     = cell.Id.ChildBegin;
            double exactArea   = 0;
            double approxArea  = 0;
            double averageArea = 0;

            for (var i = 0; i < 4; ++i, childId = childId.Next)
            {
                exactArea   += children[i].ExactArea();
                approxArea  += children[i].ApproxArea();
                averageArea += children[i].AverageArea();

                // Check that the child geometry is consistent with its cell id.
                JavaAssert.Equal(children[i].Id, childId);
                Assert.True(children[i].Center.ApproxEquals(childId.ToPoint(), 1e-15));
                var direct = new S2Cell(childId);
                JavaAssert.Equal(children[i].Face, direct.Face);
                JavaAssert.Equal(children[i].Level, direct.Level);
                JavaAssert.Equal(children[i].Orientation, direct.Orientation);
                JavaAssert.Equal(children[i].CenterRaw, direct.CenterRaw);
                for (var k = 0; k < 4; ++k)
                {
                    JavaAssert.Equal(children[i].GetVertexRaw(k), direct.GetVertexRaw(k));
                    JavaAssert.Equal(children[i].GetEdgeRaw(k), direct.GetEdgeRaw(k));
                }

                // Test Contains() and MayIntersect().
                Assert.True(cell.Contains(children[i]));
                Assert.True(cell.MayIntersect(children[i]));
                Assert.True(!children[i].Contains(cell));
                Assert.True(cell.Contains(children[i].CenterRaw));
                for (var j = 0; j < 4; ++j)
                {
                    Assert.True(cell.Contains(children[i].GetVertexRaw(j)));
                    if (j != i)
                    {
                        Assert.True(!children[i].Contains(children[j].CenterRaw));
                        Assert.True(!children[i].MayIntersect(children[j]));
                    }
                }

                // Test GetCapBound and GetRectBound.
                var parentCap  = cell.CapBound;
                var parentRect = cell.RectBound;
                if (cell.Contains(new S2Point(0, 0, 1)) ||
                    cell.Contains(new S2Point(0, 0, -1)))
                {
                    Assert.True(parentRect.Lng.IsFull);
                }
                var childCap  = children[i].CapBound;
                var childRect = children[i].RectBound;
                Assert.True(childCap.Contains(children[i].Center));
                Assert.True(childRect.Contains(children[i].CenterRaw));
                Assert.True(parentCap.Contains(children[i].Center));
                Assert.True(parentRect.Contains(children[i].CenterRaw));
                for (var j = 0; j < 4; ++j)
                {
                    Assert.True(childCap.Contains(children[i].GetVertex(j)));
                    Assert.True(childRect.Contains(children[i].GetVertex(j)));
                    Assert.True(childRect.Contains(children[i].GetVertexRaw(j)));
                    Assert.True(parentCap.Contains(children[i].GetVertex(j)));
                    if (!parentRect.Contains(children[i].GetVertex(j)))
                    {
                        Console.WriteLine("cell: " + cell + " i: " + i + " j: " + j);
                        Console.WriteLine("Children " + i + ": " + children[i]);
                        Console.WriteLine("Parent rect: " + parentRect);
                        Console.WriteLine("Vertex raw(j) " + children[i].GetVertex(j));
                        Console.WriteLine("Latlng of vertex: " + new S2LatLng(children[i].GetVertex(j)));
                        Console.WriteLine("RectBound: " + cell.RectBound);
                    }
                    Assert.True(parentRect.Contains(children[i].GetVertex(j)));
                    if (!parentRect.Contains(children[i].GetVertexRaw(j)))
                    {
                        Console.WriteLine("cell: " + cell + " i: " + i + " j: " + j);
                        Console.WriteLine("Children " + i + ": " + children[i]);
                        Console.WriteLine("Parent rect: " + parentRect);
                        Console.WriteLine("Vertex raw(j) " + children[i].GetVertexRaw(j));
                        Console.WriteLine("Latlng of vertex: " + new S2LatLng(children[i].GetVertexRaw(j)));
                        Console.WriteLine("RectBound: " + cell.RectBound);
                    }
                    Assert.True(parentRect.Contains(children[i].GetVertexRaw(j)));
                    if (j != i)
                    {
                        // The bounding caps and rectangles should be tight enough so that
                        // they exclude at least two vertices of each adjacent cell.
                        var capCount  = 0;
                        var rectCount = 0;
                        for (var k = 0; k < 4; ++k)
                        {
                            if (childCap.Contains(children[j].GetVertex(k)))
                            {
                                ++capCount;
                            }
                            if (childRect.Contains(children[j].GetVertexRaw(k)))
                            {
                                ++rectCount;
                            }
                        }
                        Assert.True(capCount <= 2);
                        if (childRect.LatLo.Radians > -S2.PiOver2 &&
                            childRect.LatHi.Radians < S2.PiOver2)
                        {
                            // Bounding rectangles may be too large at the poles because the
                            // pole itself has an arbitrary fixed longitude.
                            Assert.True(rectCount <= 2);
                        }
                    }
                }

                // Check all children for the first few levels, and then sample randomly.
                // Also subdivide one corner cell, one edge cell, and one center cell
                // so that we have a better chance of sample the minimum metric values.
                var forceSubdivide = false;
                var center         = S2Projections.GetNorm(children[i].Face);
                var edge           = center + S2Projections.GetUAxis(children[i].Face);
                var corner         = edge + S2Projections.GetVAxis(children[i].Face);
                for (var j = 0; j < 4; ++j)
                {
                    var p = children[i].GetVertexRaw(j);
                    if (p.Equals(center) || p.Equals(edge) || p.Equals(corner))
                    {
                        forceSubdivide = true;
                    }
                }
                if (forceSubdivide || cell.Level < (DEBUG_MODE ? 5 : 6) ||
                    random(DEBUG_MODE ? 10 : 4) == 0)
                {
                    testSubdivide(children[i]);
                }
            }

            // Check sum of child areas equals parent area.
            //
            // For ExactArea(), the best relative error we can expect is about 1e-6
            // because the precision of the unit vector coordinates is only about 1e-15
            // and the edge length of a leaf cell is about 1e-9.
            //
            // For ApproxArea(), the areas are accurate to within a few percent.
            //
            // For AverageArea(), the areas themselves are not very accurate, but
            // the average area of a parent is exactly 4 times the area of a child.

            Assert.True(Math.Abs(Math.Log(exactArea / cell.ExactArea())) <= Math
                        .Abs(Math.Log(1 + 1e-6)));
            Assert.True(Math.Abs(Math.Log(approxArea / cell.ApproxArea())) <= Math
                        .Abs(Math.Log(1.03)));
            Assert.True(Math.Abs(Math.Log(averageArea / cell.AverageArea())) <= Math
                        .Abs(Math.Log(1 + 1e-15)));
        }
Example #15
0
        public void R1IntervalBasicTest()
        {
            // Constructors and accessors.
            var unit    = new R1Interval(0, 1);
            var negunit = new R1Interval(-1, 0);

            JavaAssert.Equal(unit.Lo, 0.0);
            JavaAssert.Equal(unit.Hi, 1.0);
            JavaAssert.Equal(negunit.Lo, -1.0);
            JavaAssert.Equal(negunit.Hi, 0.0);

            // is_empty()
            var half = new R1Interval(0.5, 0.5);

            Assert.True(!unit.IsEmpty);
            Assert.True(!half.IsEmpty);
            var empty = R1Interval.Empty;

            Assert.True(empty.IsEmpty);

            // GetCenter(), GetLength()
            JavaAssert.Equal(unit.Center, 0.5);
            JavaAssert.Equal(half.Center, 0.5);
            JavaAssert.Equal(negunit.Length, 1.0);
            JavaAssert.Equal(half.Length, 0.0);
            Assert.True(empty.Length < 0);

            // contains(double), interiorContains(double)
            Assert.True(unit.Contains(0.5));
            Assert.True(unit.InteriorContains(0.5));
            Assert.True(unit.Contains(0));
            Assert.True(!unit.InteriorContains(0));
            Assert.True(unit.Contains(1));
            Assert.True(!unit.InteriorContains(1));

            // contains(R1Interval), interiorContains(R1Interval)
            // Intersects(R1Interval), InteriorIntersects(R1Interval)
            testIntervalOps(empty, empty, "TTFF");
            testIntervalOps(empty, unit, "FFFF");
            testIntervalOps(unit, half, "TTTT");
            testIntervalOps(unit, unit, "TFTT");
            testIntervalOps(unit, empty, "TTFF");
            testIntervalOps(unit, negunit, "FFTF");
            testIntervalOps(unit, new R1Interval(0, 0.5), "TFTT");
            testIntervalOps(half, new R1Interval(0, 0.5), "FFTF");

            // addPoint()
            R1Interval r;

            r = empty.AddPoint(5);
            Assert.True(r.Lo == 5.0 && r.Hi == 5.0);
            r = r.AddPoint(-1);
            Assert.True(r.Lo == -1.0 && r.Hi == 5.0);
            r = r.AddPoint(0);
            Assert.True(r.Lo == -1.0 && r.Hi == 5.0);

            // fromPointPair()
            JavaAssert.Equal(R1Interval.FromPointPair(4, 4), new R1Interval(4, 4));
            JavaAssert.Equal(R1Interval.FromPointPair(-1, -2), new R1Interval(-2, -1));
            JavaAssert.Equal(R1Interval.FromPointPair(-5, 3), new R1Interval(-5, 3));

            // expanded()
            JavaAssert.Equal(empty.Expanded(0.45), empty);
            JavaAssert.Equal(unit.Expanded(0.5), new R1Interval(-0.5, 1.5));

            // union(), intersection()
            Assert.True(new R1Interval(99, 100).Union(empty).Equals(new R1Interval(99, 100)));
            Assert.True(empty.Union(new R1Interval(99, 100)).Equals(new R1Interval(99, 100)));
            Assert.True(new R1Interval(5, 3).Union(new R1Interval(0, -2)).IsEmpty);
            Assert.True(new R1Interval(0, -2).Union(new R1Interval(5, 3)).IsEmpty);
            Assert.True(unit.Union(unit).Equals(unit));
            Assert.True(unit.Union(negunit).Equals(new R1Interval(-1, 1)));
            Assert.True(negunit.Union(unit).Equals(new R1Interval(-1, 1)));
            Assert.True(half.Union(unit).Equals(unit));
            Assert.True(unit.Intersection(half).Equals(half));
            Assert.True(unit.Intersection(negunit).Equals(new R1Interval(0, 0)));
            Assert.True(negunit.Intersection(half).IsEmpty);
            Assert.True(unit.Intersection(empty).IsEmpty);
            Assert.True(empty.Intersection(unit).IsEmpty);
        }