Ejemplo n.º 1
0
        public static void Test2()
        {
            com.epl.geometry.MultiPoint multipoint = new com.epl.geometry.MultiPoint();
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    multipoint.Add(i, j);
                }
            }
            com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
            multipoint.QueryEnvelope2D(extent);
            com.epl.geometry.MultiPointImpl            multipointImpl = (com.epl.geometry.MultiPointImpl)multipoint._getImpl();
            com.epl.geometry.QuadTree                  quadtree       = BuildQuadTree_(multipointImpl);
            com.epl.geometry.QuadTree.QuadTreeIterator qtIter         = quadtree.GetIterator();
            NUnit.Framework.Assert.IsTrue(qtIter.Next() == -1);
            int count = 0;

            qtIter.ResetIterator(extent, 0.0);
            while (qtIter.Next() != -1)
            {
                count++;
            }
            NUnit.Framework.Assert.IsTrue(count == 10000);
        }
Ejemplo n.º 2
0
 internal static com.epl.geometry.QuadTree BuildQuadTree_(com.epl.geometry.MultiPointImpl multipointImpl)
 {
     com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
     multipointImpl.QueryEnvelope2D(extent);
     com.epl.geometry.QuadTree   quadTree    = new com.epl.geometry.QuadTree(extent, 8);
     com.epl.geometry.Envelope2D boundingbox = new com.epl.geometry.Envelope2D();
     com.epl.geometry.Point2D    pt;
     for (int i = 0; i < multipointImpl.GetPointCount(); i++)
     {
         pt = multipointImpl.GetXY(i);
         boundingbox.SetCoords(pt.x, pt.y, pt.x, pt.y);
         quadTree.Insert(i, boundingbox, -1);
     }
     return(quadTree);
 }
        public static com.epl.geometry.QuadTree BuildQuadTree(com.epl.geometry.MultiPath multipath)
        {
            com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
            multipath.QueryEnvelope2D(extent);
            com.epl.geometry.QuadTree quadTree = new com.epl.geometry.QuadTree(extent, 8);
            int hint_index = -1;

            com.epl.geometry.SegmentIterator seg_iter = multipath.QuerySegmentIterator();
            while (seg_iter.NextPath())
            {
                while (seg_iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = seg_iter.NextSegment();
                    int index = seg_iter.GetStartPointIndex();
                    com.epl.geometry.Envelope2D boundingbox = new com.epl.geometry.Envelope2D();
                    segment.QueryEnvelope2D(boundingbox);
                    hint_index = quadTree.Insert(index, boundingbox, hint_index);
                }
            }
            return(quadTree);
        }
Ejemplo n.º 4
0
        public static void Test1()
        {
            {
                com.epl.geometry.QuadTree quad_tree           = new com.epl.geometry.QuadTree(com.epl.geometry.Envelope2D.Construct(-10, -10, 10, 10), 8);
                com.epl.geometry.QuadTree.QuadTreeIterator qt = quad_tree.GetIterator(true);
                NUnit.Framework.Assert.IsTrue(qt.Next() == -1);
                qt.ResetIterator(com.epl.geometry.Envelope2D.Construct(0, 0, 0, 0), 0);
                NUnit.Framework.Assert.IsTrue(quad_tree.GetIntersectionCount(com.epl.geometry.Envelope2D.Construct(0, 0, 0, 0), 0, 10) == 0);
                NUnit.Framework.Assert.IsTrue(quad_tree.GetElementCount() == 0);
            }
            com.epl.geometry.Polyline polyline;
            polyline = MakePolyline();
            com.epl.geometry.MultiPathImpl             polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
            com.epl.geometry.QuadTree                  quadtree     = BuildQuadTree_(polylineImpl, false);
            com.epl.geometry.Line                      queryline    = new com.epl.geometry.Line(34, 9, 66, 46);
            com.epl.geometry.QuadTree.QuadTreeIterator qtIter       = quadtree.GetIterator();
            NUnit.Framework.Assert.IsTrue(qtIter.Next() == -1);
            qtIter.ResetIterator(queryline, 0.0);
            int element_handle = qtIter.Next();

            while (element_handle > 0)
            {
                int index = quadtree.GetElement(element_handle);
                NUnit.Framework.Assert.IsTrue(index == 6 || index == 8 || index == 14);
                element_handle = qtIter.Next();
            }
            com.epl.geometry.Envelope2D envelope     = new com.epl.geometry.Envelope2D(34, 9, 66, 46);
            com.epl.geometry.Polygon    queryPolygon = new com.epl.geometry.Polygon();
            queryPolygon.AddEnvelope(envelope, true);
            qtIter.ResetIterator(queryline, 0.0);
            element_handle = qtIter.Next();
            while (element_handle > 0)
            {
                int index = quadtree.GetElement(element_handle);
                NUnit.Framework.Assert.IsTrue(index == 6 || index == 8 || index == 14);
                element_handle = qtIter.Next();
            }
        }
        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);
            }
        }
Ejemplo n.º 6
0
        public static void TestQuadTreeWithDuplicates()
        {
            int pass_count   = 10;
            int figure_size  = 400;
            int figure_size2 = 100;

            com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope();
            extent1.SetCoords(-100000, -100000, 100000, 100000);
            com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figure_size, 10000), extent1, 0.001);
            System.Random random   = new System.Random(2013);
            int           rand_max = 32;

            com.epl.geometry.Polygon poly_red  = new com.epl.geometry.Polygon();
            com.epl.geometry.Polygon poly_blue = new com.epl.geometry.Polygon();
            int r = figure_size;

            for (int c = 0; c < pass_count; c++)
            {
                com.epl.geometry.Point pt;
                for (int j = 0; j < r; j++)
                {
                    int  rand         = random.Next(rand_max);
                    bool b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator1.GetRandomCoord();
                    if (j == 0 || b_random_new)
                    {
                        poly_blue.StartPath(pt);
                    }
                    else
                    {
                        poly_blue.LineTo(pt);
                    }
                }
                com.epl.geometry.Envelope2D env                       = new com.epl.geometry.Envelope2D();
                com.epl.geometry.QuadTree   quad_tree_blue            = BuildQuadTree_((com.epl.geometry.MultiPathImpl)poly_blue._getImpl(), false);
                com.epl.geometry.QuadTree   quad_tree_blue_duplicates = BuildQuadTree_((com.epl.geometry.MultiPathImpl)poly_blue._getImpl(), true);
                com.epl.geometry.Envelope2D e1 = quad_tree_blue.GetDataExtent();
                com.epl.geometry.Envelope2D e2 = quad_tree_blue_duplicates.GetDataExtent();
                NUnit.Framework.Assert.IsTrue(e1.Equals(e2));
                NUnit.Framework.Assert.IsTrue(quad_tree_blue.GetElementCount() == poly_blue.GetSegmentCount());
                com.epl.geometry.SegmentIterator seg_iter_blue = poly_blue.QuerySegmentIterator();
                poly_red.SetEmpty();
                r = figure_size2;
                if (r < 3)
                {
                    continue;
                }
                for (int j_1 = 0; j_1 < r; j_1++)
                {
                    int  rand         = random.Next(rand_max);
                    bool b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator1.GetRandomCoord();
                    if (j_1 == 0 || b_random_new)
                    {
                        poly_red.StartPath(pt);
                    }
                    else
                    {
                        poly_red.LineTo(pt);
                    }
                }
                com.epl.geometry.QuadTree.QuadTreeIterator        iterator     = quad_tree_blue.GetIterator();
                com.epl.geometry.SegmentIteratorImpl              seg_iter_red = ((com.epl.geometry.MultiPathImpl)poly_red._getImpl()).QuerySegmentIterator();
                System.Collections.Generic.Dictionary <int, bool> map1         = new System.Collections.Generic.Dictionary <int, bool>(0);
                int count = 0;
                int intersections_per_query = 0;
                while (seg_iter_red.NextPath())
                {
                    while (seg_iter_red.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment_red = seg_iter_red.NextSegment();
                        segment_red.QueryEnvelope2D(env);
                        iterator.ResetIterator(env, 0.0);
                        int count_upper = 0;
                        int element_handle;
                        while ((element_handle = iterator.Next()) != -1)
                        {
                            count_upper++;
                            int  index = quad_tree_blue.GetElement(element_handle);
                            bool iter  = map1.ContainsKey(index);
                            if (!iter)
                            {
                                count++;
                                map1[index] = true;
                            }
                            intersections_per_query++;
                        }
                        int intersection_count = quad_tree_blue.GetIntersectionCount(env, 0.0, -1);
                        NUnit.Framework.Assert.IsTrue(intersection_count == count_upper);
                    }
                }
                seg_iter_red.ResetToFirstPath();
                System.Collections.Generic.Dictionary <int, bool> map2 = new System.Collections.Generic.Dictionary <int, bool>(0);
                com.epl.geometry.QuadTree.QuadTreeIterator        iterator_duplicates = quad_tree_blue_duplicates.GetIterator();
                int count_duplicates = 0;
                int intersections_per_query_duplicates = 0;
                while (seg_iter_red.NextPath())
                {
                    while (seg_iter_red.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment_red = seg_iter_red.NextSegment();
                        segment_red.QueryEnvelope2D(env);
                        iterator_duplicates.ResetIterator(env, 0.0);
                        int count_lower = 0;
                        System.Collections.Generic.Dictionary <int, bool> map_per_query = new System.Collections.Generic.Dictionary <int, bool>(0);
                        int count_upper = 0;
                        int element_handle;
                        while ((element_handle = iterator_duplicates.Next()) != -1)
                        {
                            count_upper++;
                            int  index = quad_tree_blue_duplicates.GetElement(element_handle);
                            bool iter  = map2.ContainsKey(index);
                            if (!iter)
                            {
                                count_duplicates++;
                                map2[index] = true;
                            }
                            bool iter_lower = map_per_query.ContainsKey(index);
                            if (!iter_lower)
                            {
                                count_lower++;
                                intersections_per_query_duplicates++;
                                map_per_query[index] = true;
                            }
                            int q = quad_tree_blue_duplicates.GetQuad(element_handle);
                            NUnit.Framework.Assert.IsTrue(quad_tree_blue_duplicates.GetSubTreeElementCount(q) >= quad_tree_blue_duplicates.GetContainedSubTreeElementCount(q));
                        }
                        int  intersection_count = quad_tree_blue_duplicates.GetIntersectionCount(env, 0.0, -1);
                        bool b_has_data         = quad_tree_blue_duplicates.HasData(env, 0.0);
                        NUnit.Framework.Assert.IsTrue(b_has_data || intersection_count == 0);
                        NUnit.Framework.Assert.IsTrue(count_lower <= intersection_count && intersection_count <= count_upper);
                        NUnit.Framework.Assert.IsTrue(count_upper <= 4 * count_lower);
                    }
                }
                NUnit.Framework.Assert.IsTrue(count == count_duplicates);
                NUnit.Framework.Assert.IsTrue(intersections_per_query == intersections_per_query_duplicates);
            }
        }
Ejemplo n.º 7
0
 public static void Test_perf_quad_tree()
 {
     com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope();
     extent1.SetCoords(-1000, -1000, 1000, 1000);
     com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(1000, extent1, 0.001);
     //HiResTimer timer;
     for (int N = 16; N <= 1024; N *= 2)
     {
         //timer.StartMeasurement();
         com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
         extent.SetCoords(-1000, -1000, 1000, 1000);
         System.Collections.Generic.Dictionary <int, com.epl.geometry.Envelope2D> data = new System.Collections.Generic.Dictionary <int, com.epl.geometry.Envelope2D>(0);
         com.epl.geometry.QuadTree qt = new com.epl.geometry.QuadTree(extent, 10);
         for (int i = 0; i < N; i++)
         {
             com.epl.geometry.Envelope2D env    = new com.epl.geometry.Envelope2D();
             com.epl.geometry.Point2D    center = generator1.GetRandomCoord().GetXY();
             double w = 10;
             env.SetCoords(center, w, w);
             env.Intersect(extent);
             if (env.IsEmpty())
             {
                 continue;
             }
             int h = qt.Insert(i, env);
             data[h] = env;
         }
         int ecount = 0;
         com.epl.geometry.AttributeStreamOfInt32    handles = new com.epl.geometry.AttributeStreamOfInt32(0);
         com.epl.geometry.QuadTree.QuadTreeIterator iter    = qt.GetIterator();
         System.Collections.Generic.IEnumerator <System.Collections.Generic.KeyValuePair <int, com.epl.geometry.Envelope2D> > pairs = data.GetEnumerator();
         while (pairs.MoveNext())
         {
             System.Collections.Generic.KeyValuePair <int, com.epl.geometry.Envelope2D> entry = pairs.Current;
             iter.ResetIterator((com.epl.geometry.Envelope2D)entry.Value, 0.001);
             bool remove_self = false;
             for (int h = iter.Next(); h != -1; h = iter.Next())
             {
                 if (h != entry.Key)
                 {
                     handles.Add(h);
                 }
                 else
                 {
                     remove_self = true;
                 }
                 ecount++;
             }
             for (int i_1 = 0; i_1 < handles.Size(); i_1++)
             {
                 qt.RemoveElement(handles.Get(i_1));
             }
             //remove elements that were selected.
             if (remove_self)
             {
                 qt.RemoveElement(entry.Key);
             }
             handles.Resize(0);
         }
     }
 }
        // Tests if Ring1 is inside Ring2.
        // We assume here that the Polygon is Weak Simple. That is if one point of
        // Ring1 is found to be inside of Ring2, then
        // we assume that all of Ring1 is inside Ring2.
        internal static bool _isRingInRing2D(com.epl.geometry.MultiPath polygon, int iRing1, int iRing2, double tolerance, com.epl.geometry.QuadTree quadTree)
        {
            com.epl.geometry.MultiPathImpl       polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
            com.epl.geometry.SegmentIteratorImpl segIter     = polygonImpl.QuerySegmentIterator();
            segIter.ResetToPath(iRing1);
            if (!segIter.NextPath() || !segIter.HasNextSegment())
            {
                throw new com.epl.geometry.GeometryException("corrupted geometry");
            }
            int res = 2;

            while (res == 2 && segIter.HasNextSegment())
            {
                com.epl.geometry.Segment segment = segIter.NextSegment();
                com.epl.geometry.Point2D point   = segment.GetCoord2D(0.5);
                res = com.epl.geometry.PointInPolygonHelper.IsPointInRing(polygonImpl, iRing2, point, tolerance, quadTree);
            }
            if (res == 2)
            {
                throw com.epl.geometry.GeometryException.GeometryInternalError();
            }
            if (res == 1)
            {
                return(true);
            }
            return(false);
        }
        public static int IsPointInRing(com.epl.geometry.MultiPathImpl inputPolygonImpl, int iRing, com.epl.geometry.Point2D inputPoint, double tolerance, com.epl.geometry.QuadTree quadTree)
        {
            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            inputPolygonImpl.QueryLooseEnvelope2D(env);
            env.Inflate(tolerance, tolerance);
            if (!env.Contains(inputPoint))
            {
                return(0);
            }
            bool bAltenate = true;

            com.epl.geometry.PointInPolygonHelper helper = new com.epl.geometry.PointInPolygonHelper(bAltenate, inputPoint, tolerance);
            if (quadTree != null)
            {
                com.epl.geometry.Envelope2D queryEnv = new com.epl.geometry.Envelope2D();
                queryEnv.SetCoords(env);
                queryEnv.xmax = inputPoint.x + tolerance;
                // no need to query
                // segments to
                // the right of the
                // point.
                // Only segments to the
                // left
                // matter.
                queryEnv.ymin = inputPoint.y - tolerance;
                queryEnv.ymax = inputPoint.y + tolerance;
                com.epl.geometry.SegmentIteratorImpl       iter  = inputPolygonImpl.QuerySegmentIterator();
                com.epl.geometry.QuadTree.QuadTreeIterator qiter = quadTree.GetIterator(queryEnv, tolerance);
                for (int qhandle = qiter.Next(); qhandle != -1; qhandle = qiter.Next())
                {
                    iter.ResetToVertex(quadTree.GetElement(qhandle), iRing);
                    if (iter.HasNextSegment())
                    {
                        if (iter.GetPathIndex() != iRing)
                        {
                            continue;
                        }
                        com.epl.geometry.Segment segment = iter.NextSegment();
                        if (helper.ProcessSegment(segment))
                        {
                            return(-1);
                        }
                    }
                }
                // point on boundary
                return(helper.Result());
            }
            else
            {
                com.epl.geometry.SegmentIteratorImpl iter = inputPolygonImpl.QuerySegmentIterator();
                iter.ResetToPath(iRing);
                if (iter.NextPath())
                {
                    while (iter.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment = iter.NextSegment();
                        if (helper.ProcessSegment(segment))
                        {
                            return(-1);
                        }
                    }
                }
                // point on boundary
                return(helper.Result());
            }
        }