コード例 #1
0
    public void Test_VisitCells_QueryEdgeOnFaceBoundary()
    {
        int kIters = 100;

        for (int iter = 0; iter < kIters; ++iter)
        {
            _logger.WriteLine("Iteration " + iter);

            // Choose an edge AB such that B is nearly on the edge between two S2 cube
            // faces, and such that the result of clipping AB to the face that nominally
            // contains B (according to S2.GetFace) is empty when no padding is used.
            int     a_face, b_face;
            S2Point a, b;
            R2Point a_uv, b_uv;
            do
            {
                a_face = S2Testing.Random.Uniform(6);
                a      = S2.FaceUVtoXYZ(a_face, S2Testing.Random.UniformDouble(-1, 1),
                                        S2Testing.Random.UniformDouble(-1, 1)).Normalize();
                b_face = S2.GetUVWFace(a_face, 0, 1);  // Towards positive u-axis
                var uTmp = 1 - S2Testing.Random.Uniform(2) * 0.5 * S2.DoubleEpsilon;
                b = S2.FaceUVtoXYZ(b_face, uTmp, S2Testing.Random.UniformDouble(-1, 1)).Normalize();
            } while (S2.GetFace(b) != b_face ||
                     S2EdgeClipping.ClipToFace(a, b, b_face, out a_uv, out b_uv));

            // Verify that the clipping result is non-empty when a padding of
            // S2EdgeClipping.kFaceClipErrorUVCoord is used instead.
            Assert.True(S2EdgeClipping.ClipToPaddedFace(a, b, b_face, S2EdgeClipping.kFaceClipErrorUVCoord,
                                                        out a_uv, out b_uv));

            // Create an S2ShapeIndex containing a single edge BC, where C is on the
            // same S2 cube face as B (which is different than the face containing A).
            S2Point c = S2.FaceUVtoXYZ(b_face, S2Testing.Random.UniformDouble(-1, 1),
                                       S2Testing.Random.UniformDouble(-1, 1)).Normalize();
            MutableS2ShapeIndex index = new();
            index.Add(new S2Polyline.OwningShape(
                          new S2Polyline(new S2Point[] { b, c })));

            // Check that the intersection between AB and BC is detected when the face
            // containing BC is specified as a root cell.  (Note that VisitCells()
            // returns false only if the CellVisitor returns false, and otherwise
            // returns true.)
            S2CrossingEdgeQuery query = new(index);
            S2PaddedCell        root  = new(S2CellId.FromFace(b_face), 0);
            Assert.False(query.VisitCells(a, b, root, (S2ShapeIndexCell x) => false));
        }
    }
コード例 #2
0
    // Returns true if any edge of the indexed shape "clipped" intersects the
    // cell "target".  It may also return true if an edge is very close to
    // "target"; the maximum error is less than 10 * S2Constants.DoubleEpsilon radians (about
    // 15 nanometers).
    private bool AnyEdgeIntersects(S2ClippedShape clipped, S2Cell target)
    {
        var bound     = target.BoundUV.Expanded(kMaxError);
        var face      = target.Face;
        var shape     = Index().Shape(clipped.ShapeId);
        int num_edges = clipped.NumEdges;

        for (int i = 0; i < num_edges; ++i)
        {
            var edge = shape.GetEdge(clipped.Edge(i));
            if (S2EdgeClipping.ClipToPaddedFace(edge.V0, edge.V1, face, kMaxError, out var p0, out var p1) &&
                S2EdgeClipping.IntersectsRect(p0, p1, bound))
            {
                return(true);
            }
        }
        return(false);
    }