Esempio n. 1
0
        public void testFaceUVtoXYZ()
        {
            // Check that each face appears exactly once.
            var sum = new S2Point();

            for (var face = 0; face < 6; ++face)
            {
                var center = S2Projections.FaceUvToXyz(face, 0, 0);
                assertEquals(S2Projections.GetNorm(face), center);
                assertEquals(Math.Abs(center[center.LargestAbsComponent]), 1.0);
                sum = sum + S2Point.Fabs(center);
            }
            assertEquals(sum, new S2Point(2, 2, 2));

            // Check that each face has a right-handed coordinate system.
            for (var face = 0; face < 6; ++face)
            {
                assertEquals(
                    S2Point.CrossProd(S2Projections.GetUAxis(face), S2Projections.GetVAxis(face)).DotProd(
                        S2Projections.FaceUvToXyz(face, 0, 0)), 1.0);
            }

            // Check that the Hilbert curves on each face combine to form a
            // continuous curve over the entire cube.
            for (var face = 0; face < 6; ++face)
            {
                // The Hilbert curve on each face starts at (-1,-1) and terminates
                // at either (1,-1) (if axes not swapped) or (-1,1) (if swapped).
                var sign = ((face & S2.SwapMask) != 0) ? -1 : 1;
                assertEquals(S2Projections.FaceUvToXyz(face, sign, -sign),
                             S2Projections.FaceUvToXyz((face + 1) % 6, -1, -1));
            }
        }
Esempio n. 2
0
 public void testUVAxes()
 {
     // Check that axes are consistent with FaceUVtoXYZ.
     for (var face = 0; face < 6; ++face)
     {
         assertEquals(S2Projections.GetUAxis(face),
                      S2Projections.FaceUvToXyz(face, 1, 0) - S2Projections.FaceUvToXyz(face, 0, 0));
         assertEquals(S2Projections.GetVAxis(face),
                      S2Projections.FaceUvToXyz(face, 0, 1) - S2Projections.FaceUvToXyz(face, 0, 0));
     }
 }
        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)));
        }