internal static com.epl.geometry.Envelope2DIntersectorImpl GetEnvelope2DIntersector(com.epl.geometry.MultiPathImpl multipathImplA, com.epl.geometry.MultiPathImpl multipathImplB, double tolerance)
        {
            com.epl.geometry.Envelope2D env_a = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D env_b = new com.epl.geometry.Envelope2D();
            multipathImplA.QueryLooseEnvelope2D(env_a);
            multipathImplB.QueryLooseEnvelope2D(env_b);
            env_a.Inflate(tolerance, tolerance);
            env_b.Inflate(tolerance, tolerance);
            com.epl.geometry.Envelope2D envInter = new com.epl.geometry.Envelope2D();
            envInter.SetCoords(env_a);
            envInter.Intersect(env_b);
            com.epl.geometry.SegmentIteratorImpl       segIterA    = multipathImplA.QuerySegmentIterator();
            com.epl.geometry.SegmentIteratorImpl       segIterB    = multipathImplB.QuerySegmentIterator();
            com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector.SetTolerance(tolerance);
            bool b_found_red = false;

            intersector.StartRedConstruction();
            while (segIterA.NextPath())
            {
                while (segIterA.HasNextSegment())
                {
                    com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                    segmentA.QueryEnvelope2D(env_a);
                    if (!env_a.IsIntersecting(envInter))
                    {
                        continue;
                    }
                    b_found_red = true;
                    com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                    env.SetCoords(env_a);
                    intersector.AddRedEnvelope(segIterA.GetStartPointIndex(), env);
                }
            }
            intersector.EndRedConstruction();
            if (!b_found_red)
            {
                return(null);
            }
            bool b_found_blue = false;

            intersector.StartBlueConstruction();
            while (segIterB.NextPath())
            {
                while (segIterB.HasNextSegment())
                {
                    com.epl.geometry.Segment segmentB = segIterB.NextSegment();
                    segmentB.QueryEnvelope2D(env_b);
                    if (!env_b.IsIntersecting(envInter))
                    {
                        continue;
                    }
                    b_found_blue = true;
                    com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                    env.SetCoords(env_b);
                    intersector.AddBlueEnvelope(segIterB.GetStartPointIndex(), env);
                }
            }
            intersector.EndBlueConstruction();
            if (!b_found_blue)
            {
                return(null);
            }
            return(intersector);
        }
        internal static com.epl.geometry.Envelope2DIntersectorImpl GetEnvelope2DIntersectorForParts(com.epl.geometry.MultiPathImpl multipathImplA, com.epl.geometry.MultiPathImpl multipathImplB, double tolerance, bool bExteriorOnlyA, bool bExteriorOnlyB)
        {
            int type_a = multipathImplA.GetType().Value();
            int type_b = multipathImplB.GetType().Value();

            com.epl.geometry.Envelope2D env_a = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D env_b = new com.epl.geometry.Envelope2D();
            multipathImplA.QueryLooseEnvelope2D(env_a);
            multipathImplB.QueryLooseEnvelope2D(env_b);
            env_a.Inflate(tolerance, tolerance);
            env_b.Inflate(tolerance, tolerance);
            com.epl.geometry.Envelope2D envInter = new com.epl.geometry.Envelope2D();
            envInter.SetCoords(env_a);
            envInter.Intersect(env_b);
            com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector.SetTolerance(tolerance);
            bool b_found_red = false;

            intersector.StartRedConstruction();
            for (int ipath_a = 0, npaths = multipathImplA.GetPathCount(); ipath_a < npaths; ipath_a++)
            {
                if (bExteriorOnlyA && type_a == com.epl.geometry.Geometry.GeometryType.Polygon && !multipathImplA.IsExteriorRing(ipath_a))
                {
                    continue;
                }
                multipathImplA.QueryPathEnvelope2D(ipath_a, env_a);
                if (!env_a.IsIntersecting(envInter))
                {
                    continue;
                }
                b_found_red = true;
                intersector.AddRedEnvelope(ipath_a, env_a);
            }
            intersector.EndRedConstruction();
            if (!b_found_red)
            {
                return(null);
            }
            bool b_found_blue = false;

            intersector.StartBlueConstruction();
            for (int ipath_b = 0, npaths = multipathImplB.GetPathCount(); ipath_b < npaths; ipath_b++)
            {
                if (bExteriorOnlyB && type_b == com.epl.geometry.Geometry.GeometryType.Polygon && !multipathImplB.IsExteriorRing(ipath_b))
                {
                    continue;
                }
                multipathImplB.QueryPathEnvelope2D(ipath_b, env_b);
                if (!env_b.IsIntersecting(envInter))
                {
                    continue;
                }
                b_found_blue = true;
                intersector.AddBlueEnvelope(ipath_b, env_b);
            }
            intersector.EndBlueConstruction();
            if (!b_found_blue)
            {
                return(null);
            }
            return(intersector);
        }
        public static void TestRandom()
        {
            int passcount   = 10;
            int figureSize  = 100;
            int figureSize2 = 100;

            com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope();
            com.epl.geometry.Envelope extent2 = new com.epl.geometry.Envelope();
            com.epl.geometry.Envelope extent3 = new com.epl.geometry.Envelope();
            com.epl.geometry.Envelope extent4 = new com.epl.geometry.Envelope();
            extent1.SetCoords(-10000, 5000, 10000, 25000);
            // red
            extent2.SetCoords(-10000, 2000, 10000, 8000);
            // blue
            extent3.SetCoords(-10000, -8000, 10000, -2000);
            // blue
            extent4.SetCoords(-10000, -25000, 10000, -5000);
            // red
            com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent1, 0.001);
            com.epl.geometry.RandomCoordinateGenerator generator2 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent2, 0.001);
            com.epl.geometry.RandomCoordinateGenerator generator3 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent3, 0.001);
            com.epl.geometry.RandomCoordinateGenerator generator4 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent4, 0.001);
            System.Random random   = new System.Random(1982);
            int           rand_max = 511;
            int           qCount   = 0;
            int           eCount   = 0;
            int           bCount   = 0;

            for (int c = 0; c < passcount; c++)
            {
                com.epl.geometry.Polygon polyRed  = new com.epl.geometry.Polygon();
                com.epl.geometry.Polygon polyBlue = new com.epl.geometry.Polygon();
                int r = figureSize;
                if (r < 3)
                {
                    continue;
                }
                com.epl.geometry.Point pt;
                for (int j = 0; j < r; j++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator1.GetRandomCoord();
                    if (j == 0 || bRandomNew)
                    {
                        polyRed.StartPath(pt);
                    }
                    else
                    {
                        polyRed.LineTo(pt);
                    }
                }
                for (int j_1 = 0; j_1 < r; j_1++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator4.GetRandomCoord();
                    if (j_1 == 0 || bRandomNew)
                    {
                        polyRed.StartPath(pt);
                    }
                    else
                    {
                        polyRed.LineTo(pt);
                    }
                }
                r = figureSize2;
                if (r < 3)
                {
                    continue;
                }
                for (int j_2 = 0; j_2 < r; j_2++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator2.GetRandomCoord();
                    if (j_2 == 0 || bRandomNew)
                    {
                        polyBlue.StartPath(pt);
                    }
                    else
                    {
                        polyBlue.LineTo(pt);
                    }
                }
                for (int j_3 = 0; j_3 < r; j_3++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator3.GetRandomCoord();
                    if (j_3 == 0 || bRandomNew)
                    {
                        polyBlue.StartPath(pt);
                    }
                    else
                    {
                        polyBlue.LineTo(pt);
                    }
                }
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                // Quad_tree
                com.epl.geometry.QuadTree quadTree = BuildQuadTree(polyBlue);
                com.epl.geometry.QuadTree.QuadTreeIterator iterator    = quadTree.GetIterator();
                com.epl.geometry.SegmentIteratorImpl       _segIterRed = ((com.epl.geometry.MultiPathImpl)polyRed._getImpl()).QuerySegmentIterator();
                while (_segIterRed.NextPath())
                {
                    while (_segIterRed.HasNextSegment())
                    {
                        com.epl.geometry.Segment segmentRed = _segIterRed.NextSegment();
                        segmentRed.QueryEnvelope2D(env);
                        iterator.ResetIterator(env, 0.001);
                        while (iterator.Next() != -1)
                        {
                            qCount++;
                        }
                    }
                }
                // Envelope_2D_intersector
                System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes_red  = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>();
                System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes_blue = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>();
                com.epl.geometry.SegmentIterator segIterRed = polyRed.QuerySegmentIterator();
                while (segIterRed.NextPath())
                {
                    while (segIterRed.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment = segIterRed.NextSegment();
                        env = new com.epl.geometry.Envelope2D();
                        segment.QueryEnvelope2D(env);
                        envelopes_red.Add(env);
                    }
                }
                com.epl.geometry.SegmentIterator segIterBlue = polyBlue.QuerySegmentIterator();
                while (segIterBlue.NextPath())
                {
                    while (segIterBlue.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment = segIterBlue.NextSegment();
                        env = new com.epl.geometry.Envelope2D();
                        segment.QueryEnvelope2D(env);
                        envelopes_blue.Add(env);
                    }
                }
                com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
                intersector.SetTolerance(0.001);
                intersector.StartRedConstruction();
                for (int i = 0; i < envelopes_red.Count; i++)
                {
                    intersector.AddRedEnvelope(i, envelopes_red[i]);
                }
                intersector.EndRedConstruction();
                intersector.StartBlueConstruction();
                for (int i_1 = 0; i_1 < envelopes_blue.Count; i_1++)
                {
                    intersector.AddBlueEnvelope(i_1, envelopes_blue[i_1]);
                }
                intersector.EndBlueConstruction();
                while (intersector.Next())
                {
                    eCount++;
                }
                NUnit.Framework.Assert.IsTrue(qCount == eCount);
            }
        }