internal static com.epl.geometry.Geometry CalculateConvexHull_(com.epl.geometry.Geometry geom, com.epl.geometry.ProgressTracker progress_tracker)
 {
     if (geom.IsEmpty())
     {
         return(geom.CreateInstance());
     }
     com.epl.geometry.Geometry.Type type = geom.GetType();
     if (com.epl.geometry.Geometry.IsSegment(type.Value()))
     {
         // Segments are always returned either as a Point or Polyline
         com.epl.geometry.Segment segment = (com.epl.geometry.Segment)geom;
         if (segment.GetStartXY().Equals(segment.GetEndXY()))
         {
             com.epl.geometry.Point point = new com.epl.geometry.Point();
             segment.QueryStart(point);
             return(point);
         }
         else
         {
             com.epl.geometry.Point    pt       = new com.epl.geometry.Point();
             com.epl.geometry.Polyline polyline = new com.epl.geometry.Polyline(geom.GetDescription());
             segment.QueryStart(pt);
             polyline.StartPath(pt);
             segment.QueryEnd(pt);
             polyline.LineTo(pt);
             return(polyline);
         }
     }
     else
     {
         if (type == com.epl.geometry.Geometry.Type.Envelope)
         {
             com.epl.geometry.Envelope   envelope = (com.epl.geometry.Envelope)geom;
             com.epl.geometry.Envelope2D env      = new com.epl.geometry.Envelope2D();
             envelope.QueryEnvelope2D(env);
             if (env.xmin == env.xmax && env.ymin == env.ymax)
             {
                 com.epl.geometry.Point point = new com.epl.geometry.Point();
                 envelope.QueryCornerByVal(0, point);
                 return(point);
             }
             else
             {
                 if (env.xmin == env.xmax || env.ymin == env.ymax)
                 {
                     com.epl.geometry.Point    pt       = new com.epl.geometry.Point();
                     com.epl.geometry.Polyline polyline = new com.epl.geometry.Polyline(geom.GetDescription());
                     envelope.QueryCornerByVal(0, pt);
                     polyline.StartPath(pt);
                     envelope.QueryCornerByVal(1, pt);
                     polyline.LineTo(pt);
                     return(polyline);
                 }
                 else
                 {
                     com.epl.geometry.Polygon polygon = new com.epl.geometry.Polygon(geom.GetDescription());
                     polygon.AddEnvelope(envelope, false);
                     return(polygon);
                 }
             }
         }
     }
     if (IsConvex_(geom, progress_tracker))
     {
         if (type == com.epl.geometry.Geometry.Type.MultiPoint)
         {
             // Downgrade to a Point for simplistic output
             com.epl.geometry.MultiPoint multi_point = (com.epl.geometry.MultiPoint)geom;
             com.epl.geometry.Point      point       = new com.epl.geometry.Point();
             multi_point.GetPointByVal(0, point);
             return(point);
         }
         return(geom);
     }
     System.Diagnostics.Debug.Assert((com.epl.geometry.Geometry.IsMultiVertex(type.Value())));
     com.epl.geometry.Geometry convex_hull = com.epl.geometry.ConvexHull.Construct((com.epl.geometry.MultiVertexGeometry)geom);
     return(convex_hull);
 }
 public SegmentBuffer()
 {
     // PointerOf(Bezier) m_bez;
     m_line = null;
     m_seg  = null;
 }
Beispiel #3
0
        // se.m_segment = se.m_segment_sptr.get();
        // Compares seg_1 and seg_2 x coordinates of intersection with the line
        // parallel to axis x, passing through the coordinate y.
        // If segments intersect not at the endpoint, the m_b_intersection_detected
        // is set.
        internal virtual int CompareTwoSegments_(com.epl.geometry.Segment seg_1, com.epl.geometry.Segment seg_2)
        {
            int res = seg_1._isIntersecting(seg_2, m_tolerance, true);

            if (res != 0)
            {
                if (res == 2)
                {
                    return(ErrorCoincident());
                }
                else
                {
                    return(ErrorCracking());
                }
            }
            com.epl.geometry.Point2D start_1 = seg_1.GetStartXY();
            com.epl.geometry.Point2D end1    = seg_1.GetEndXY();
            com.epl.geometry.Point2D start2  = seg_2.GetStartXY();
            com.epl.geometry.Point2D end2    = seg_2.GetEndXY();
            com.epl.geometry.Point2D ptSweep = new com.epl.geometry.Point2D();
            ptSweep.SetCoords(m_sweep_x, m_sweep_y);
            if (start_1.IsEqual(start2) && m_sweep_y == start_1.y)
            {
                System.Diagnostics.Debug.Assert((start_1.Compare(end1) < 0 && start2.Compare(end2) < 0));
                if (end1.Compare(end2) < 0)
                {
                    ptSweep.SetCoords(end1);
                }
                else
                {
                    ptSweep.SetCoords(end2);
                }
            }
            else
            {
                if (start_1.IsEqual(end2) && m_sweep_y == start_1.y)
                {
                    System.Diagnostics.Debug.Assert((start_1.Compare(end1) < 0 && start2.Compare(end2) > 0));
                    if (end1.Compare(start2) < 0)
                    {
                        ptSweep.SetCoords(end1);
                    }
                    else
                    {
                        ptSweep.SetCoords(start2);
                    }
                }
                else
                {
                    if (start2.IsEqual(end1) && m_sweep_y == start2.y)
                    {
                        System.Diagnostics.Debug.Assert((end1.Compare(start_1) < 0 && start2.Compare(end2) < 0));
                        if (start_1.Compare(end2) < 0)
                        {
                            ptSweep.SetCoords(start_1);
                        }
                        else
                        {
                            ptSweep.SetCoords(end2);
                        }
                    }
                    else
                    {
                        if (end1.IsEqual(end2) && m_sweep_y == end1.y)
                        {
                            System.Diagnostics.Debug.Assert((start_1.Compare(end1) > 0 && start2.Compare(end2) > 0));
                            if (start_1.Compare(start2) < 0)
                            {
                                ptSweep.SetCoords(start_1);
                            }
                            else
                            {
                                ptSweep.SetCoords(start2);
                            }
                        }
                    }
                }
            }
            double xleft  = seg_1.IntersectionOfYMonotonicWithAxisX(ptSweep.y, ptSweep.x);
            double xright = seg_2.IntersectionOfYMonotonicWithAxisX(ptSweep.y, ptSweep.x);

            System.Diagnostics.Debug.Assert((xleft != xright));
            return(xleft < xright ? -1 : 1);
        }
 private com.epl.geometry.SegmentIntersector.IntersectionPart NewIntersectionPart_(com.epl.geometry.Segment _seg)
 {
     if ((m_recycled_intersection_parts.Count == 0))
     {
         com.epl.geometry.SegmentIntersector.IntersectionPart part = new com.epl.geometry.SegmentIntersector.IntersectionPart(_seg);
         return(part);
     }
     else
     {
         com.epl.geometry.SegmentIntersector.IntersectionPart part = m_recycled_intersection_parts[m_recycled_intersection_parts.Count - 1];
         part.seg = _seg;
         m_recycled_intersection_parts.RemoveAt(m_recycled_intersection_parts.Count - 1);
         return(part);
     }
 }
Beispiel #5
0
            private double BruteForceMultiPathMultiPoint_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPoint geometryB, bool geometriesAreDisjoint)
            {
                /* const */
                /* const */
                com.epl.geometry.SegmentIterator segIterA      = geometryA.QuerySegmentIterator();
                com.epl.geometry.Envelope2D      env2DSegmentA = new com.epl.geometry.Envelope2D();
                double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax();

                com.epl.geometry.Point2D inputPoint = new com.epl.geometry.Point2D();
                double t           = -1;
                double sqrDistance = minSqrDistance;

                /* const */
                com.epl.geometry.MultiPointImpl multiPointImplB = (com.epl.geometry.MultiPointImpl)geometryB._getImpl();
                int  pointCountB = multiPointImplB.GetPointCount();
                bool bDoPiPTest  = !geometriesAreDisjoint && (geometryA.GetType() == com.epl.geometry.Geometry.Type.Polygon);

                while (segIterA.NextPath())
                {
                    while (segIterA.HasNextSegment())
                    {
                        /* const */
                        com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                        segmentA.QueryEnvelope2D(env2DSegmentA);
                        // if multipointB has only 1 vertex then it is faster to not
                        // test for
                        // env2DSegmentA.distance(env2DgeometryB)
                        if (pointCountB > 1 && env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance)
                        {
                            continue;
                        }
                        for (int i = 0; i < pointCountB; i++)
                        {
                            multiPointImplB.GetXY(i, inputPoint);
                            if (bDoPiPTest)
                            {
                                // Test for polygon containment. This takes the
                                // place of a more general intersection test at the
                                // beginning of the operator
                                if (com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geometryA, inputPoint, 0) != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                                {
                                    return(0.0);
                                }
                            }
                            t = segmentA.GetClosestCoordinate(inputPoint, false);
                            inputPoint.Sub(segmentA.GetCoord2D(t));
                            sqrDistance = inputPoint.SqrLength();
                            if (sqrDistance < minSqrDistance)
                            {
                                if (sqrDistance == 0.0)
                                {
                                    return(0.0);
                                }
                                minSqrDistance = sqrDistance;
                            }
                        }
                        // No need to do point-in-polygon anymore (if it is a
                        // polygon vs polyline)
                        bDoPiPTest = false;
                    }
                }
                return(System.Math.Sqrt(minSqrDistance));
            }
Beispiel #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);
            }
        }
Beispiel #7
0
        private bool CrackBruteForce_()
        {
            com.epl.geometry.EditShape.VertexIterator iter_1 = m_shape.QueryVertexIterator(false);
            bool b_cracked = false;

            com.epl.geometry.Line       line_1    = new com.epl.geometry.Line();
            com.epl.geometry.Line       line_2    = new com.epl.geometry.Line();
            com.epl.geometry.Envelope2D seg_1_env = new com.epl.geometry.Envelope2D();
            seg_1_env.SetEmpty();
            com.epl.geometry.Envelope2D seg_2_env = new com.epl.geometry.Envelope2D();
            seg_2_env.SetEmpty();
            bool assume_intersecting = false;

            com.epl.geometry.Point helper_point = new com.epl.geometry.Point();
            com.epl.geometry.SegmentIntersector segment_intersector = new com.epl.geometry.SegmentIntersector();
            for (int vertex_1 = iter_1.Next(); vertex_1 != -1; vertex_1 = iter_1.Next())
            {
                com.epl.geometry.ProgressTracker.CheckAndThrow(m_progress_tracker);
                int GT_1 = m_shape.GetGeometryType(iter_1.CurrentGeometry());
                com.epl.geometry.Segment seg_1 = null;
                bool seg_1_zero = false;
                if (!com.epl.geometry.Geometry.IsPoint(GT_1))
                {
                    seg_1 = GetSegment_(vertex_1, line_1);
                    if (seg_1 == null)
                    {
                        continue;
                    }
                    seg_1.QueryEnvelope2D(seg_1_env);
                    seg_1_env.Inflate(m_tolerance, m_tolerance);
                    if (seg_1.IsDegenerate(m_tolerance))
                    {
                        // do not crack with
                        // degenerate segments
                        if (seg_1.IsDegenerate(0))
                        {
                            seg_1_zero = true;
                            seg_1      = null;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                com.epl.geometry.EditShape.VertexIterator iter_2 = m_shape.QueryVertexIterator(iter_1);
                int vertex_2 = iter_2.Next();
                if (vertex_2 != -1)
                {
                    vertex_2 = iter_2.Next();
                }
                for (; vertex_2 != -1; vertex_2 = iter_2.Next())
                {
                    int GT_2 = m_shape.GetGeometryType(iter_2.CurrentGeometry());
                    com.epl.geometry.Segment seg_2 = null;
                    bool seg_2_zero = false;
                    if (!com.epl.geometry.Geometry.IsPoint(GT_2))
                    {
                        seg_2 = GetSegment_(vertex_2, line_2);
                        if (seg_2 == null)
                        {
                            continue;
                        }
                        seg_2.QueryEnvelope2D(seg_2_env);
                        if (seg_2.IsDegenerate(m_tolerance))
                        {
                            // do not crack with
                            // degenerate segments
                            if (seg_2.IsDegenerate(0))
                            {
                                seg_2_zero = true;
                                seg_2      = null;
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    int split_count_1 = 0;
                    int split_count_2 = 0;
                    if (seg_1 != null && seg_2 != null)
                    {
                        if (seg_1_env.IsIntersectingNE(seg_2_env))
                        {
                            segment_intersector.PushSegment(seg_1);
                            segment_intersector.PushSegment(seg_2);
                            segment_intersector.Intersect(m_tolerance, assume_intersecting);
                            split_count_1 = segment_intersector.GetResultSegmentCount(0);
                            split_count_2 = segment_intersector.GetResultSegmentCount(1);
                            if (split_count_1 + split_count_2 > 0)
                            {
                                m_shape.SplitSegment_(vertex_1, segment_intersector, 0, true);
                                m_shape.SplitSegment_(vertex_2, segment_intersector, 1, true);
                            }
                            segment_intersector.Clear();
                        }
                    }
                    else
                    {
                        if (seg_1 != null)
                        {
                            com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
                            m_shape.GetXY(vertex_2, pt);
                            if (seg_1_env.Contains(pt))
                            {
                                segment_intersector.PushSegment(seg_1);
                                m_shape.QueryPoint(vertex_2, helper_point);
                                segment_intersector.Intersect(m_tolerance, helper_point, 0, 1.0, assume_intersecting);
                                split_count_1 = segment_intersector.GetResultSegmentCount(0);
                                if (split_count_1 > 0)
                                {
                                    m_shape.SplitSegment_(vertex_1, segment_intersector, 0, true);
                                    if (seg_2_zero)
                                    {
                                        //seg_2 was zero length. Need to change all coincident points
                                        //segment at vertex_2 is dzero length, change all attached zero length segments
                                        int v_to = -1;
                                        for (int v = m_shape.GetNextVertex(vertex_2); v != -1 && v != vertex_2; v = m_shape.GetNextVertex(v))
                                        {
                                            seg_2 = GetSegment_(v, line_2);
                                            v_to  = v;
                                            if (seg_2 == null || !seg_2.IsDegenerate(0))
                                            {
                                                break;
                                            }
                                        }
                                        //change from vertex_2 to v_to (inclusive).
                                        for (int v_1 = vertex_2; v_1 != -1; v_1 = m_shape.GetNextVertex(v_1))
                                        {
                                            m_shape.SetPoint(v_1, segment_intersector.GetResultPoint());
                                            if (v_1 == v_to)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        m_shape.SetPoint(vertex_2, segment_intersector.GetResultPoint());
                                    }
                                }
                                segment_intersector.Clear();
                            }
                        }
                        else
                        {
                            if (seg_2 != null)
                            {
                                com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
                                m_shape.GetXY(vertex_1, pt);
                                seg_2_env.Inflate(m_tolerance, m_tolerance);
                                if (seg_2_env.Contains(pt))
                                {
                                    segment_intersector.PushSegment(seg_2);
                                    m_shape.QueryPoint(vertex_1, helper_point);
                                    segment_intersector.Intersect(m_tolerance, helper_point, 0, 1.0, assume_intersecting);
                                    split_count_2 = segment_intersector.GetResultSegmentCount(0);
                                    if (split_count_2 > 0)
                                    {
                                        m_shape.SplitSegment_(vertex_2, segment_intersector, 0, true);
                                        if (seg_1_zero)
                                        {
                                            //seg_1 was zero length. Need to change all coincident points
                                            //segment at vertex_2 is dzero length, change all attached zero length segments
                                            int v_to = -1;
                                            for (int v = m_shape.GetNextVertex(vertex_1); v != -1 && v != vertex_1; v = m_shape.GetNextVertex(v))
                                            {
                                                seg_2 = GetSegment_(v, line_2);
                                                //using here seg_2 for seg_1
                                                v_to = v;
                                                if (seg_2 == null || !seg_2.IsDegenerate(0))
                                                {
                                                    break;
                                                }
                                            }
                                            //change from vertex_2 to v_to (inclusive).
                                            for (int v_1 = vertex_1; v_1 != -1; v_1 = m_shape.GetNextVertex(v_1))
                                            {
                                                m_shape.SetPoint(v_1, segment_intersector.GetResultPoint());
                                                if (v_1 == v_to)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            m_shape.SetPoint(vertex_1, segment_intersector.GetResultPoint());
                                        }
                                    }
                                    segment_intersector.Clear();
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    // points on points
                    if (split_count_1 + split_count_2 != 0)
                    {
                        if (split_count_1 != 0)
                        {
                            seg_1 = m_shape.GetSegment(vertex_1);
                            // reload segment
                            // after split
                            if (seg_1 == null)
                            {
                                if (!m_shape.QueryLineConnector(vertex_1, line_1))
                                {
                                    continue;
                                }
                                seg_1 = line_1;
                                line_1.QueryEnvelope2D(seg_1_env);
                            }
                            else
                            {
                                seg_1.QueryEnvelope2D(seg_1_env);
                            }
                            if (seg_1.IsDegenerate(m_tolerance))
                            {
                                // do not crack with
                                // degenerate
                                // segments
                                break;
                            }
                        }
                        b_cracked = true;
                    }
                }
            }
            return(b_cracked);
        }
        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());
            }
        }
        private void DoOne(com.epl.geometry.Segment seg)
        {
            if (!m_bTestBorder)
            {
                // test if point is on the boundary
                if (m_bAlternate && m_inputPoint.IsEqual(seg.GetStartXY()) || m_inputPoint.IsEqual(seg.GetEndXY()))
                {
                    // test if the
                    // point
                    // coincides
                    // with a vertex
                    m_bBreak = true;
                    return;
                }
            }
            if (seg.GetStartY() == m_inputPoint.y && seg.GetStartY() == seg.GetEndY())
            {
                // skip horizontal
                // segments. test if the
                // point lies on a
                // horizontal segment
                if (m_bAlternate && !m_bTestBorder)
                {
                    double minx = System.Math.Min(seg.GetStartX(), seg.GetEndX());
                    double maxx = System.Math.Max(seg.GetStartX(), seg.GetEndX());
                    if (m_inputPoint.x > minx && m_inputPoint.x < maxx)
                    {
                        m_bBreak = true;
                    }
                }
                return;
            }
            // skip horizontal segments
            bool   bToTheRight = false;
            double maxx_1      = System.Math.Max(seg.GetStartX(), seg.GetEndX());

            if (m_inputPoint.x > maxx_1)
            {
                bToTheRight = true;
            }
            else
            {
                if (m_inputPoint.x >= System.Math.Min(seg.GetStartX(), seg.GetEndX()))
                {
                    int n = seg.IntersectionWithAxis2D(true, m_inputPoint.y, m_xOrds, null);
                    bToTheRight = n > 0 && m_xOrds[0] <= m_inputPoint.x;
                }
            }
            if (bToTheRight)
            {
                // to prevent double counting, when the ray crosses a vertex, count
                // only the segments that are below the ray.
                if (m_inputPoint.y == seg.GetStartXY().y)
                {
                    if (m_inputPoint.y < seg.GetEndXY().y)
                    {
                        return;
                    }
                }
                else
                {
                    if (m_inputPoint.y == seg.GetEndXY().y)
                    {
                        if (m_inputPoint.y < seg.GetStartXY().y)
                        {
                            return;
                        }
                    }
                }
                if (m_bAlternate)
                {
                    m_windnum ^= 1;
                }
                else
                {
                    m_windnum += (seg.GetStartXY().y > seg.GetEndXY().y) ? 1 : -1;
                }
            }
        }
Beispiel #10
0
            internal override int Compare(com.epl.geometry.Treap treap, int left, int node)
            {
                int right = treap.GetElement(node);

                com.epl.geometry.RingOrientationFixer.Edges edges = this.m_helper.m_edges;
                double x_1;

                if (this.m_left_elm == left)
                {
                    x_1 = this.m_leftx;
                }
                else
                {
                    this.m_seg_1 = edges.GetSegment(left);
                    if (this.m_seg_1 == null)
                    {
                        com.epl.geometry.EditShape shape = edges.GetShape();
                        shape.QueryLineConnector(edges.GetStart(left), this.m_line_1);
                        this.m_seg_1 = this.m_line_1;
                        x_1          = this.m_line_1.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                    }
                    else
                    {
                        x_1 = this.m_seg_1.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                    }
                    this.m_leftx    = x_1;
                    this.m_left_elm = left;
                }
                com.epl.geometry.Segment seg_2 = edges.GetSegment(right);
                double x2;

                if (seg_2 == null)
                {
                    com.epl.geometry.EditShape shape = edges.GetShape();
                    shape.QueryLineConnector(edges.GetStart(right), this.m_line_2);
                    seg_2 = this.m_line_2;
                    x2    = this.m_line_2.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                }
                else
                {
                    x2 = seg_2.IntersectionOfYMonotonicWithAxisX(this.m_helper.m_y_scanline, 0);
                }
                if (x_1 == x2)
                {
                    bool bStartLower1 = edges.IsBottomUp(left);
                    bool bStartLower2 = edges.IsBottomUp(right);
                    // apparently these edges originate from same vertex and the
                    // scanline is on the vertex. move scanline a little.
                    double y1 = !bStartLower1?this.m_seg_1.GetStartY() : this.m_seg_1.GetEndY();

                    double y2 = !bStartLower2?seg_2.GetStartY() : seg_2.GetEndY();

                    double miny = System.Math.Min(y1, y2);
                    double y    = (miny + this.m_helper.m_y_scanline) * 0.5;
                    if (y == this.m_helper.m_y_scanline)
                    {
                        // assert(0);//ST: not a bug. just curious to see this
                        // happens.
                        y = miny;
                    }
                    // apparently, one of the segments is almost
                    // horizontal line.
                    x_1 = this.m_seg_1.IntersectionOfYMonotonicWithAxisX(y, 0);
                    x2  = seg_2.IntersectionOfYMonotonicWithAxisX(y, 0);
                    System.Diagnostics.Debug.Assert((x_1 != x2));
                }
                return(x_1 < x2 ? -1 : (x_1 > x2 ? 1 : 0));
            }
        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);
        }
Beispiel #12
0
 internal abstract void _copyToImpl(com.epl.geometry.Segment dst);
Beispiel #13
0
 /// <summary>
 /// Returns TRUE if this segment intersects with the other segment with the
 /// given tolerance.
 /// </summary>
 public virtual bool IsIntersecting(com.epl.geometry.Segment other, double tolerance)
 {
     return(_isIntersecting(other, tolerance, false) != 0);
 }
Beispiel #14
0
 /// <summary>Calculates intersections of this segment with another segment.</summary>
 /// <remarks>
 /// Calculates intersections of this segment with another segment.
 /// <p>
 /// Note: This is not a topological operation. It needs to be paired with the
 /// Segment.Overlap call.
 /// </remarks>
 /// <param name="other">The segment to calculate intersection with.</param>
 /// <param name="intersectionPoints">The intersection points. Can be NULL.</param>
 /// <param name="paramThis">
 /// The value of the parameter in the intersection points for this
 /// Segment (between 0 and 1). Can be NULL.
 /// </param>
 /// <param name="paramOther">
 /// The value of the parameter in the intersection points for the
 /// other Segment (between 0 and 1). Can be NULL.
 /// </param>
 /// <param name="tolerance">
 /// The tolerance value for the intersection calculation. Can be
 /// 0.
 /// </param>
 /// <returns>
 /// The number of intersection points, 0 when no intersection points
 /// exist.
 /// </returns>
 internal virtual int Intersect(com.epl.geometry.Segment other, com.epl.geometry.Point2D[] intersectionPoints, double[] paramThis, double[] paramOther, double tolerance)
 {
     return(_intersect(other, intersectionPoints, paramThis, paramOther, tolerance));
 }
 internal static bool IsConvex_(com.epl.geometry.Geometry geom, com.epl.geometry.ProgressTracker progress_tracker)
 {
     if (geom.IsEmpty())
     {
         return(true);
     }
     // vacuously true
     com.epl.geometry.Geometry.Type type = geom.GetType();
     if (type == com.epl.geometry.Geometry.Type.Point)
     {
         return(true);
     }
     // vacuously true
     if (type == com.epl.geometry.Geometry.Type.Envelope)
     {
         com.epl.geometry.Envelope envelope = (com.epl.geometry.Envelope)geom;
         if (envelope.GetXMin() == envelope.GetXMax() || envelope.GetYMin() == envelope.GetYMax())
         {
             return(false);
         }
         return(true);
     }
     if (com.epl.geometry.MultiPath.IsSegment(type.Value()))
     {
         com.epl.geometry.Segment segment = (com.epl.geometry.Segment)geom;
         if (segment.GetStartXY().Equals(segment.GetEndXY()))
         {
             return(false);
         }
         return(true);
     }
     // true, but we will upgrade to a Polyline for the ConvexHull operation
     if (type == com.epl.geometry.Geometry.Type.MultiPoint)
     {
         com.epl.geometry.MultiPoint multi_point = (com.epl.geometry.MultiPoint)geom;
         if (multi_point.GetPointCount() == 1)
         {
             return(true);
         }
         // vacuously true, but we will downgrade to a Point for the ConvexHull operation
         return(false);
     }
     if (type == com.epl.geometry.Geometry.Type.Polyline)
     {
         com.epl.geometry.Polyline polyline = (com.epl.geometry.Polyline)geom;
         if (polyline.GetPathCount() == 1 && polyline.GetPointCount() == 2)
         {
             if (!polyline.GetXY(0).Equals(polyline.GetXY(1)))
             {
                 return(true);
             }
         }
         // vacuously true
         return(false);
     }
     // create convex hull
     com.epl.geometry.Polygon polygon = (com.epl.geometry.Polygon)geom;
     if (polygon.GetPathCount() != 1 || polygon.GetPointCount() < 3)
     {
         return(false);
     }
     return(com.epl.geometry.ConvexHull.IsPathConvex(polygon, 0, progress_tracker));
 }
        internal virtual com.epl.geometry.Geometry TryFastIntersectPolylinePolygon_(com.epl.geometry.Polyline polyline, com.epl.geometry.Polygon polygon)
        {
            com.epl.geometry.MultiPathImpl polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
            com.epl.geometry.MultiPathImpl polygonImpl  = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
            double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, polygon, false);

            com.epl.geometry.Envelope2D clipEnvelope = new com.epl.geometry.Envelope2D();
            {
                polygonImpl.QueryEnvelope2D(clipEnvelope);
                com.epl.geometry.Envelope2D env1 = new com.epl.geometry.Envelope2D();
                polylineImpl.QueryEnvelope2D(env1);
                env1.Inflate(2.0 * tolerance, 2.0 * tolerance);
                clipEnvelope.Intersect(env1);
                System.Diagnostics.Debug.Assert((!clipEnvelope.IsEmpty()));
            }
            clipEnvelope.Inflate(10 * tolerance, 10 * tolerance);
            if (true)
            {
                double tol = 0;
                com.epl.geometry.Geometry clippedPolyline = com.epl.geometry.Clipper.Clip(polyline, clipEnvelope, tol, 0.0);
                polyline     = (com.epl.geometry.Polyline)clippedPolyline;
                polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
            }
            com.epl.geometry.AttributeStreamOfInt32 clipResult = new com.epl.geometry.AttributeStreamOfInt32(0);
            int unresolvedSegments = -1;

            com.epl.geometry.GeometryAccelerators accel = polygonImpl._getAccelerators();
            if (accel != null)
            {
                com.epl.geometry.RasterizedGeometry2D rgeom = accel.GetRasterizedGeometry();
                if (rgeom != null)
                {
                    unresolvedSegments = 0;
                    clipResult.Reserve(polylineImpl.GetPointCount() + polylineImpl.GetPathCount());
                    com.epl.geometry.Envelope2D          seg_env = new com.epl.geometry.Envelope2D();
                    com.epl.geometry.SegmentIteratorImpl iter    = polylineImpl.QuerySegmentIterator();
                    while (iter.NextPath())
                    {
                        while (iter.HasNextSegment())
                        {
                            com.epl.geometry.Segment seg = iter.NextSegment();
                            seg.QueryEnvelope2D(seg_env);
                            com.epl.geometry.RasterizedGeometry2D.HitType hit = rgeom.QueryEnvelopeInGeometry(seg_env);
                            if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside)
                            {
                                clipResult.Add(1);
                            }
                            else
                            {
                                if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside)
                                {
                                    clipResult.Add(0);
                                }
                                else
                                {
                                    clipResult.Add(-1);
                                    unresolvedSegments++;
                                }
                            }
                        }
                    }
                }
            }
            if (polygon.GetPointCount() > 5)
            {
                double tol = 0;
                com.epl.geometry.Geometry clippedPolygon = com.epl.geometry.Clipper.Clip(polygon, clipEnvelope, tol, 0.0);
                polygon     = (com.epl.geometry.Polygon)clippedPolygon;
                polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
                accel       = polygonImpl._getAccelerators();
            }
            //update accelerators
            if (unresolvedSegments < 0)
            {
                unresolvedSegments = polylineImpl.GetSegmentCount();
            }
            // Some heuristics to decide if it makes sense to go with fast intersect
            // vs going with the regular planesweep.
            double totalPoints             = (double)(polylineImpl.GetPointCount() + polygonImpl.GetPointCount());
            double thisAlgorithmComplexity = ((double)unresolvedSegments * polygonImpl.GetPointCount());
            // assume the worst case.
            double planesweepComplexity            = System.Math.Log(totalPoints) * totalPoints;
            double empiricConstantFactorPlaneSweep = 4;

            if (thisAlgorithmComplexity > planesweepComplexity * empiricConstantFactorPlaneSweep)
            {
                // Based on the number of input points, we deduced that the
                // plansweep performance should be better than the brute force
                // performance.
                return(null);
            }
            // resort to planesweep if quadtree does not help
            com.epl.geometry.QuadTreeImpl        polygonQuadTree = null;
            com.epl.geometry.SegmentIteratorImpl polygonIter     = polygonImpl.QuerySegmentIterator();
            // Some logic to decide if it makes sense to build a quadtree on the
            // polygon segments
            if (accel != null && accel.GetQuadTree() != null)
            {
                polygonQuadTree = accel.GetQuadTree();
            }
            if (polygonQuadTree == null && polygonImpl.GetPointCount() > 20)
            {
                polygonQuadTree = com.epl.geometry.InternalUtils.BuildQuadTree(polygonImpl);
            }
            com.epl.geometry.Polyline      result_polyline           = (com.epl.geometry.Polyline)polyline.CreateInstance();
            com.epl.geometry.MultiPathImpl resultPolylineImpl        = (com.epl.geometry.MultiPathImpl)result_polyline._getImpl();
            com.epl.geometry.QuadTreeImpl.QuadTreeIteratorImpl qIter = null;
            com.epl.geometry.SegmentIteratorImpl polylineIter        = polylineImpl.QuerySegmentIterator();
            double[] @params = new double[9];
            com.epl.geometry.AttributeStreamOfDbl intersections = new com.epl.geometry.AttributeStreamOfDbl(0);
            com.epl.geometry.SegmentBuffer        segmentBuffer = new com.epl.geometry.SegmentBuffer();
            int  start_index = -1;
            int  inCount     = 0;
            int  segIndex    = 0;
            bool bOptimized  = clipResult.Size() > 0;
            // The algorithm is like that:
            // Loop through all the segments of the polyline.
            // For each polyline segment, intersect it with each of the polygon
            // segments.
            // If no intersections found then,
            // If the polyline segment is completely inside, it is added to the
            // result polyline.
            // If it is outside, it is thrown out.
            // If it intersects, then cut the polyline segment to pieces and test
            // each part of the intersected result.
            // The cut pieces will either have one point inside, or one point
            // outside, or the middle point inside/outside.
            //
            int polylinePathIndex = -1;

            while (polylineIter.NextPath())
            {
                polylinePathIndex = polylineIter.GetPathIndex();
                int stateNewPath                  = 0;
                int stateAddSegment               = 1;
                int stateManySegments             = 2;
                int stateManySegmentsContinuePath = 2;
                int stateManySegmentsNewPath      = 3;
                int state = stateNewPath;
                start_index = -1;
                inCount     = 0;
                while (polylineIter.HasNextSegment())
                {
                    int clipStatus = bOptimized ? (int)clipResult.Get(segIndex) : -1;
                    segIndex++;
                    com.epl.geometry.Segment polylineSeg = polylineIter.NextSegment();
                    if (clipStatus < 0)
                    {
                        System.Diagnostics.Debug.Assert((clipStatus == -1));
                        // Analyse polyline segment for intersection with the
                        // polygon.
                        if (polygonQuadTree != null)
                        {
                            if (qIter == null)
                            {
                                qIter = polygonQuadTree.GetIterator(polylineSeg, tolerance);
                            }
                            else
                            {
                                qIter.ResetIterator(polylineSeg, tolerance);
                            }
                            int path_index = -1;
                            for (int ind = qIter.Next(); ind != -1; ind = qIter.Next())
                            {
                                polygonIter.ResetToVertex(polygonQuadTree.GetElement(ind));
                                // path_index
                                path_index = polygonIter.GetPathIndex();
                                com.epl.geometry.Segment polygonSeg = polygonIter.NextSegment();
                                // intersect polylineSeg and polygonSeg.
                                int count = polylineSeg.Intersect(polygonSeg, null, @params, null, tolerance);
                                for (int i = 0; i < count; i++)
                                {
                                    intersections.Add(@params[i]);
                                }
                            }
                        }
                        else
                        {
                            // no quadtree built
                            polygonIter.ResetToFirstPath();
                            while (polygonIter.NextPath())
                            {
                                while (polygonIter.HasNextSegment())
                                {
                                    com.epl.geometry.Segment polygonSeg = polygonIter.NextSegment();
                                    // intersect polylineSeg and polygonSeg.
                                    int count = polylineSeg.Intersect(polygonSeg, null, @params, null, tolerance);
                                    for (int i = 0; i < count; i++)
                                    {
                                        intersections.Add(@params[i]);
                                    }
                                }
                            }
                        }
                        if (intersections.Size() > 0)
                        {
                            // intersections detected.
                            intersections.Sort(0, intersections.Size());
                            // std::sort(intersections.begin(),
                            // intersections.end());
                            double t0 = 0;
                            intersections.Add(1.0);
                            int status = -1;
                            for (int i = 0, n = intersections.Size(); i < n; i++)
                            {
                                double t = intersections.Get(i);
                                if (t == t0)
                                {
                                    continue;
                                }
                                bool bWholeSegment = false;
                                com.epl.geometry.Segment resSeg;
                                if (t0 != 0 || t != 1.0)
                                {
                                    polylineSeg.Cut(t0, t, segmentBuffer);
                                    resSeg = segmentBuffer.Get();
                                }
                                else
                                {
                                    resSeg        = polylineSeg;
                                    bWholeSegment = true;
                                }
                                if (state >= stateManySegments)
                                {
                                    resultPolylineImpl.AddSegmentsFromPath(polylineImpl, polylinePathIndex, start_index, inCount, state == stateManySegmentsNewPath);
                                    if (AnalyseClipSegment_(polygon, resSeg.GetStartXY(), tolerance) != 1)
                                    {
                                        if (AnalyseClipSegment_(polygon, resSeg, tolerance) != 1)
                                        {
                                            return(null);
                                        }
                                    }
                                    //someting went wrong we'll falback to slower but robust planesweep code.
                                    resultPolylineImpl.AddSegment(resSeg, false);
                                    state   = stateAddSegment;
                                    inCount = 0;
                                }
                                else
                                {
                                    status = AnalyseClipSegment_(polygon, resSeg, tolerance);
                                    switch (status)
                                    {
                                    case 1:
                                    {
                                        if (!bWholeSegment)
                                        {
                                            resultPolylineImpl.AddSegment(resSeg, state == stateNewPath);
                                            state = stateAddSegment;
                                        }
                                        else
                                        {
                                            if (state < stateManySegments)
                                            {
                                                start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
                                                inCount     = 1;
                                                if (state == stateNewPath)
                                                {
                                                    state = stateManySegmentsNewPath;
                                                }
                                                else
                                                {
                                                    System.Diagnostics.Debug.Assert((state == stateAddSegment));
                                                    state = stateManySegmentsContinuePath;
                                                }
                                            }
                                            else
                                            {
                                                inCount++;
                                            }
                                        }
                                        break;
                                    }

                                    case 0:
                                    {
                                        state       = stateNewPath;
                                        start_index = -1;
                                        inCount     = 0;
                                        break;
                                    }

                                    default:
                                    {
                                        return(null);
                                    }
                                    }
                                }
                                // may happen if a segment
                                // coincides with the border.
                                t0 = t;
                            }
                        }
                        else
                        {
                            clipStatus = AnalyseClipSegment_(polygon, polylineSeg.GetStartXY(), tolerance);
                            // simple
                            // case
                            // no
                            // intersection.
                            // Both
                            // points
                            // must
                            // be
                            // inside.
                            if (clipStatus < 0)
                            {
                                System.Diagnostics.Debug.Assert((clipStatus >= 0));
                                return(null);
                            }
                            // something goes wrong, resort to
                            // planesweep
                            System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg.GetEndXY(), tolerance) == clipStatus));
                            if (clipStatus == 1)
                            {
                                // the whole segment inside
                                if (state < stateManySegments)
                                {
                                    System.Diagnostics.Debug.Assert((inCount == 0));
                                    start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
                                    if (state == stateNewPath)
                                    {
                                        state = stateManySegmentsNewPath;
                                    }
                                    else
                                    {
                                        System.Diagnostics.Debug.Assert((state == stateAddSegment));
                                        state = stateManySegmentsContinuePath;
                                    }
                                }
                                inCount++;
                            }
                            else
                            {
                                System.Diagnostics.Debug.Assert((state < stateManySegments));
                                start_index = -1;
                                inCount     = 0;
                            }
                        }
                        intersections.Clear(false);
                    }
                    else
                    {
                        // clip status is determined by other means
                        if (clipStatus == 0)
                        {
                            // outside
                            System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg, tolerance) == 0));
                            System.Diagnostics.Debug.Assert((start_index < 0));
                            System.Diagnostics.Debug.Assert((inCount == 0));
                            continue;
                        }
                        if (clipStatus == 1)
                        {
                            System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg, tolerance) == 1));
                            if (state == stateNewPath)
                            {
                                state       = stateManySegmentsNewPath;
                                start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
                            }
                            else
                            {
                                if (state == stateAddSegment)
                                {
                                    state       = stateManySegmentsContinuePath;
                                    start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
                                }
                                else
                                {
                                    System.Diagnostics.Debug.Assert((state >= stateManySegments));
                                }
                            }
                            inCount++;
                            continue;
                        }
                    }
                }
                if (state >= stateManySegments)
                {
                    resultPolylineImpl.AddSegmentsFromPath(polylineImpl, polylinePathIndex, start_index, inCount, state == stateManySegmentsNewPath);
                    start_index = -1;
                }
            }
            return(result_polyline);
        }
Beispiel #17
0
        public void _updateSegment()
        {
            if (m_nextSegmentIndex < 0 || m_nextSegmentIndex >= m_segmentCount)
            {
                throw new System.IndexOutOfRangeException();
            }
            m_currentSegmentIndex = m_nextSegmentIndex;
            int startVertexIndex = GetStartPointIndex();

            m_parent._verifyAllStreams();
            com.epl.geometry.AttributeStreamOfInt8 segFlagStream = m_parent.GetSegmentFlagsStreamRef();
            int segFlag = com.epl.geometry.SegmentFlags.enumLineSeg;

            if (segFlagStream != null)
            {
                segFlag = (segFlagStream.Read(startVertexIndex) & com.epl.geometry.SegmentFlags.enumSegmentMask);
            }
            com.epl.geometry.VertexDescription vertexDescr = m_parent.GetDescription();
            switch (segFlag)
            {
            case com.epl.geometry.SegmentFlags.enumLineSeg:
            {
                if (m_line == null)
                {
                    m_line = new com.epl.geometry.Line();
                }
                m_currentSegment = (com.epl.geometry.Line)m_line;
                break;
            }

            case com.epl.geometry.SegmentFlags.enumBezierSeg:
            {
                throw com.epl.geometry.GeometryException.GeometryInternalError();
            }

            case com.epl.geometry.SegmentFlags.enumArcSeg:
            {
                // break;
                throw com.epl.geometry.GeometryException.GeometryInternalError();
            }

            default:
            {
                // break;
                throw com.epl.geometry.GeometryException.GeometryInternalError();
            }
            }
            m_currentSegment.AssignVertexDescription(vertexDescr);
            int endVertexIndex = GetEndPointIndex();

            m_parent.GetXY(startVertexIndex, m_dummyPoint);
            m_currentSegment.SetStartXY(m_dummyPoint);
            m_parent.GetXY(endVertexIndex, m_dummyPoint);
            m_currentSegment.SetEndXY(m_dummyPoint);
            for (int i = 1, nattr = vertexDescr.GetAttributeCount(); i < nattr; i++)
            {
                int semantics = vertexDescr.GetSemantics(i);
                int ncomp     = com.epl.geometry.VertexDescription.GetComponentCount(semantics);
                for (int ord = 0; ord < ncomp; ord++)
                {
                    double vs = m_parent.GetAttributeAsDbl(semantics, startVertexIndex, ord);
                    m_currentSegment.SetStartAttribute(semantics, ord, vs);
                    double ve = m_parent.GetAttributeAsDbl(semantics, endVertexIndex, ord);
                    m_currentSegment.SetEndAttribute(semantics, ord, ve);
                }
            }
        }
Beispiel #18
0
 internal override void _copyToImpl(com.epl.geometry.Segment dst)
 {
 }
        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);
            }
        }
        internal virtual com.epl.geometry.Proximity2DResult MultiPathGetNearestCoordinate(com.epl.geometry.MultiPath geom, com.epl.geometry.Point2D inputPoint, bool bTestPolygonInterior, bool bCalculateLeftRightSide)
        {
            if (geom.GetType() == com.epl.geometry.Geometry.Type.Polygon && bTestPolygonInterior)
            {
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                geom.QueryEnvelope2D(env);
                double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(null, env, false);
                com.epl.geometry.PolygonUtils.PiPResult pipResult;
                if (bCalculateLeftRightSide)
                {
                    pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, 0.0);
                }
                else
                {
                    pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, tolerance);
                }
                if (pipResult != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                {
                    com.epl.geometry.Proximity2DResult result = new com.epl.geometry.Proximity2DResult(inputPoint, 0, 0.0);
                    if (bCalculateLeftRightSide)
                    {
                        result.SetRightSide(true);
                    }
                    return(result);
                }
            }
            com.epl.geometry.SegmentIterator segIter = geom.QuerySegmentIterator();
            com.epl.geometry.Point2D         closest = new com.epl.geometry.Point2D();
            int    closestVertexIndex = -1;
            int    closestPathIndex   = -1;
            double closestDistanceSq  = com.epl.geometry.NumberUtils.DoubleMax();
            bool   bRight             = false;
            int    num_candidates     = 0;

            while (segIter.NextPath())
            {
                while (segIter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = segIter.NextSegment();
                    double t = segment.GetClosestCoordinate(inputPoint, false);
                    com.epl.geometry.Point2D point = segment.GetCoord2D(t);
                    double distanceSq = com.epl.geometry.Point2D.SqrDistance(point, inputPoint);
                    if (distanceSq < closestDistanceSq)
                    {
                        num_candidates     = 1;
                        closest            = point;
                        closestVertexIndex = segIter.GetStartPointIndex();
                        closestPathIndex   = segIter.GetPathIndex();
                        closestDistanceSq  = distanceSq;
                    }
                    else
                    {
                        if (distanceSq == closestDistanceSq)
                        {
                            num_candidates++;
                        }
                    }
                }
            }
            com.epl.geometry.Proximity2DResult result_1 = new com.epl.geometry.Proximity2DResult(closest, closestVertexIndex, System.Math.Sqrt(closestDistanceSq));
            if (bCalculateLeftRightSide)
            {
                segIter.ResetToVertex(closestVertexIndex, closestPathIndex);
                com.epl.geometry.Segment segment = segIter.NextSegment();
                bRight = (com.epl.geometry.Point2D.OrientationRobust(inputPoint, segment.GetStartXY(), segment.GetEndXY()) < 0);
                if (num_candidates > 1)
                {
                    com.epl.geometry.OperatorProximity2DLocal.Side_helper sideHelper = new com.epl.geometry.OperatorProximity2DLocal.Side_helper(this);
                    sideHelper.Reset();
                    bRight = sideHelper.Calc_side(inputPoint, bRight, geom, closestVertexIndex, closestPathIndex);
                }
                result_1.SetRightSide(bRight);
            }
            return(result_1);
        }
Beispiel #21
0
        public static void TestIntervalTree_RandomConstruction()
        {
            int pointcount = 0;
            int passcount  = 1000;
            int figureSize = 50;

            com.epl.geometry.Envelope env = new com.epl.geometry.Envelope();
            env.SetCoords(-10000, -10000, 10000, 10000);
            com.epl.geometry.RandomCoordinateGenerator generator = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), env, 0.001);
            System.Random random   = new System.Random(2013);
            int           rand_max = 98765;

            System.Collections.Generic.List <com.epl.geometry.Envelope1D> intervals = new System.Collections.Generic.List <com.epl.geometry.Envelope1D>();
            com.epl.geometry.AttributeStreamOfInt8 intervalsFound = new com.epl.geometry.AttributeStreamOfInt8(0);
            for (int i = 0; i < passcount; i++)
            {
                int r = figureSize;
                if (r < 3)
                {
                    continue;
                }
                com.epl.geometry.Polygon poly = new com.epl.geometry.Polygon();
                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 = generator.GetRandomCoord();
                    if (j == 0 || bRandomNew)
                    {
                        poly.StartPath(pt);
                    }
                    else
                    {
                        poly.LineTo(pt);
                    }
                }
                {
                    intervals.Clear();
                    com.epl.geometry.SegmentIterator seg_iter = poly.QuerySegmentIterator();
                    com.epl.geometry.Envelope1D      interval;
                    com.epl.geometry.Envelope1D      range = poly.QueryInterval(com.epl.geometry.VertexDescription.Semantics.POSITION, 0);
                    range.vmin -= 0.01;
                    range.vmax += 0.01;
                    while (seg_iter.NextPath())
                    {
                        while (seg_iter.HasNextSegment())
                        {
                            com.epl.geometry.Segment segment = seg_iter.NextSegment();
                            interval = segment.QueryInterval(com.epl.geometry.VertexDescription.Semantics.POSITION, 0);
                            intervals.Add(interval);
                        }
                    }
                    intervalsFound.Resize(intervals.Count, 0);
                    // Just test construction for assertions
                    com.epl.geometry.IntervalTreeImpl intervalTree = new com.epl.geometry.IntervalTreeImpl(true);
                    Construct(intervalTree, intervals);
                    for (int j_1 = 0; j_1 < intervals.Count; j_1++)
                    {
                        intervalTree.Insert(j_1);
                    }
                    com.epl.geometry.IntervalTreeImpl.IntervalTreeIteratorImpl iterator = intervalTree.GetIterator(range, 0.0);
                    int count = 0;
                    int handle;
                    while ((handle = iterator.Next()) != -1)
                    {
                        count++;
                        intervalsFound.Write(handle, unchecked ((byte)1));
                    }
                    NUnit.Framework.Assert.IsTrue(count == intervals.Count);
                    for (int j_2 = 0; j_2 < intervalsFound.Size(); j_2++)
                    {
                        interval = intervals[j_2];
                        NUnit.Framework.Assert.IsTrue(intervalsFound.Read(j_2) == 1);
                    }
                    for (int j_3 = 0; j_3 < intervals.Count >> 1; j_3++)
                    {
                        intervalTree.Remove(j_3);
                    }
                    iterator.ResetIterator(range, 0.0);
                    count = 0;
                    while ((handle = iterator.Next()) != -1)
                    {
                        count++;
                        intervalsFound.Write(handle, unchecked ((byte)1));
                    }
                    NUnit.Framework.Assert.IsTrue(count == intervals.Count - (intervals.Count >> 1));
                    for (int j_4 = (intervals.Count >> 1); j_4 < intervals.Count; j_4++)
                    {
                        intervalTree.Remove(j_4);
                    }
                }
            }
        }
 internal virtual void Find_analysis_pair_from_index(com.epl.geometry.Point2D inputPoint, com.epl.geometry.SegmentIterator segIter, int vertexIndex, int pathIndex)
 {
     this.m_i1 = this.Find_non_degenerate(segIter, vertexIndex, pathIndex);
     if (this.m_i1 != -1)
     {
         segIter.ResetToVertex(this.m_i1, -1);
         com.epl.geometry.Segment segment1 = segIter.NextSegment();
         double t1 = segment1.GetClosestCoordinate(inputPoint, false);
         com.epl.geometry.Point2D p1 = segment1.GetCoord2D(t1);
         double d1 = com.epl.geometry.Point2D.SqrDistance(p1, inputPoint);
         com.epl.geometry.Point2D pq = new com.epl.geometry.Point2D();
         pq.SetCoords(p1);
         pq.Sub(segment1.GetStartXY());
         com.epl.geometry.Point2D pr = new com.epl.geometry.Point2D();
         pr.SetCoords(inputPoint);
         pr.Sub(segment1.GetStartXY());
         this.m_bRight1 = (pq.CrossProduct(pr) < 0);
         this.m_i2      = this.Find_next_non_degenerate(segIter, this.m_i1);
         if (this.m_i2 != -1)
         {
             segIter.ResetToVertex(this.m_i2, -1);
             com.epl.geometry.Segment segment2 = segIter.NextSegment();
             double t2 = segment2.GetClosestCoordinate(inputPoint, false);
             com.epl.geometry.Point2D p2 = segment2.GetCoord2D(t2);
             double d2 = com.epl.geometry.Point2D.SqrDistance(p2, inputPoint);
             if (d2 > d1)
             {
                 this.m_i2 = -1;
             }
             else
             {
                 pq.SetCoords(p2);
                 pq.Sub(segment2.GetStartXY());
                 pr.SetCoords(inputPoint);
                 pr.Sub(segment2.GetStartXY());
                 this.m_bRight2 = (pq.CrossProduct(pr) < 0);
             }
         }
         if (this.m_i2 == -1)
         {
             this.m_i2 = this.Find_prev_non_degenerate(segIter, this.m_i1);
             if (this.m_i2 != -1)
             {
                 segIter.ResetToVertex(this.m_i2, -1);
                 com.epl.geometry.Segment segment2 = segIter.NextSegment();
                 double t2 = segment2.GetClosestCoordinate(inputPoint, false);
                 com.epl.geometry.Point2D p2 = segment2.GetCoord2D(t2);
                 double d2 = com.epl.geometry.Point2D.SqrDistance(p2, inputPoint);
                 if (d2 > d1)
                 {
                     this.m_i2 = -1;
                 }
                 else
                 {
                     pq.SetCoords(p2);
                     pq.Sub(segment2.GetStartXY());
                     pr.SetCoords(inputPoint);
                     pr.Sub(segment2.GetStartXY());
                     this.m_bRight2 = (pq.CrossProduct(pr) < 0);
                     int itemp = this.m_i1;
                     this.m_i1 = this.m_i2;
                     this.m_i2 = itemp;
                     bool btemp = this.m_bRight1;
                     this.m_bRight1 = this.m_bRight2;
                     this.m_bRight2 = btemp;
                 }
             }
         }
     }
 }
Beispiel #23
0
            private double BruteForceMultiPathMultiPath_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPath geometryB, bool geometriesAreDisjoint)
            {
                /* const */
                /* const */
                // It may be beneficial to have the geometry with less vertices
                // always be geometryA.
                com.epl.geometry.SegmentIterator segIterA      = geometryA.QuerySegmentIterator();
                com.epl.geometry.SegmentIterator segIterB      = geometryB.QuerySegmentIterator();
                com.epl.geometry.Envelope2D      env2DSegmentA = new com.epl.geometry.Envelope2D();
                com.epl.geometry.Envelope2D      env2DSegmentB = new com.epl.geometry.Envelope2D();
                double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax();

                if (!geometriesAreDisjoint)
                {
                    // Geometries might be non-disjoint. Check if they intersect
                    // using point-in-polygon tests
                    if (this.WeakIntersectionTest_(geometryA, geometryB, segIterA, segIterB))
                    {
                        return(0.0);
                    }
                }
                // if geometries are known disjoint, don't bother to do any tests
                // for polygon containment
                // nested while-loop insanity
                while (segIterA.NextPath())
                {
                    while (segIterA.HasNextSegment())
                    {
                        /* const */
                        com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                        segmentA.QueryEnvelope2D(env2DSegmentA);
                        if (env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance)
                        {
                            continue;
                        }
                        while (segIterB.NextPath())
                        {
                            while (segIterB.HasNextSegment())
                            {
                                /* const */
                                com.epl.geometry.Segment segmentB = segIterB.NextSegment();
                                segmentB.QueryEnvelope2D(env2DSegmentB);
                                if (env2DSegmentA.SqrDistance(env2DSegmentB) < minSqrDistance)
                                {
                                    // get distance between segments
                                    double sqrDistance = segmentA.Distance(segmentB, geometriesAreDisjoint);
                                    sqrDistance *= sqrDistance;
                                    if (sqrDistance < minSqrDistance)
                                    {
                                        if (sqrDistance == 0.0)
                                        {
                                            return(0.0);
                                        }
                                        minSqrDistance = sqrDistance;
                                    }
                                }
                            }
                        }
                        segIterB.ResetToFirstPath();
                    }
                }
                return(System.Math.Sqrt(minSqrDistance));
            }
 private com.epl.geometry.Geometry DensifyMultiPath(com.epl.geometry.MultiPath geom)
 {
     com.epl.geometry.MultiPath       densifiedPoly = (com.epl.geometry.MultiPath)geom.CreateInstance();
     com.epl.geometry.SegmentIterator iter          = geom.QuerySegmentIterator();
     while (iter.NextPath())
     {
         bool bStartNewPath = true;
         while (iter.HasNextSegment())
         {
             com.epl.geometry.Segment seg = iter.NextSegment();
             if (seg.GetType().Value() != com.epl.geometry.Geometry.GeometryType.Line)
             {
                 throw new com.epl.geometry.GeometryException("not implemented");
             }
             bool   bIsClosing = iter.IsClosingSegment();
             double len        = seg.CalculateLength2D();
             if (len > m_maxLength)
             {
                 // need to split
                 double dcount = System.Math.Ceiling(len / m_maxLength);
                 com.epl.geometry.Point point = new com.epl.geometry.Point(geom.GetDescription());
                 // LOCALREFCLASS1(Point,
                 // VertexDescription,
                 // point,
                 // geom.getDescription());
                 if (bStartNewPath)
                 {
                     bStartNewPath = false;
                     seg.QueryStart(point);
                     densifiedPoly.StartPath(point);
                 }
                 double dt = 1.0 / dcount;
                 double t  = dt;
                 for (int i = 0, n = (int)dcount - 1; i < n; i++)
                 {
                     seg.QueryCoord(t, point);
                     densifiedPoly.LineTo(point);
                     t += dt;
                 }
                 if (!bIsClosing)
                 {
                     seg.QueryEnd(point);
                     densifiedPoly.LineTo(point);
                 }
                 else
                 {
                     densifiedPoly.ClosePathWithLine();
                 }
                 bStartNewPath = false;
             }
             else
             {
                 if (!bIsClosing)
                 {
                     densifiedPoly.AddSegment(seg, bStartNewPath);
                 }
                 else
                 {
                     densifiedPoly.ClosePathWithLine();
                 }
                 bStartNewPath = false;
             }
         }
     }
     return((com.epl.geometry.Geometry)densifiedPoly);
 }
Beispiel #25
0
 public override void AddSegment(com.epl.geometry.Segment segment, bool bStartNewPath)
 {
     m_impl.AddSegment(segment, bStartNewPath);
 }
 /// <summary>Adds a new segment to this multipath.</summary>
 /// <param name="segment">The segment to be added to this mulitpath.</param>
 /// <param name="bStartNewPath">TRUE if a new path will be added.</param>
 public virtual void AddSegment(com.epl.geometry.Segment segment, bool bStartNewPath)
 {
     m_impl.AddSegment(segment, bStartNewPath);
 }
        internal virtual bool RgHelper(com.epl.geometry.RasterizedGeometry2D rg, com.epl.geometry.MultiPath mp)
        {
            com.epl.geometry.SegmentIterator iter = mp.QuerySegmentIterator();
            while (iter.NextPath())
            {
                while (iter.HasNextSegment())
                {
                    com.epl.geometry.Segment seg = iter.NextSegment();
                    int count = 20;
                    for (int i = 0; i < count; i++)
                    {
                        double t = (1.0 * i / count);
                        com.epl.geometry.Point2D pt = seg.GetCoord2D(t);
                        com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(pt.x, pt.y);
                        if (hit != com.epl.geometry.RasterizedGeometry2D.HitType.Border)
                        {
                            return(false);
                        }
                    }
                }
            }
            if (mp.GetType() != com.epl.geometry.Geometry.Type.Polygon)
            {
                return(true);
            }
            com.epl.geometry.Polygon    poly = (com.epl.geometry.Polygon)mp;
            com.epl.geometry.Envelope2D env  = new com.epl.geometry.Envelope2D();
            poly.QueryEnvelope2D(env);
            int count_1 = 100;

            for (int iy = 0; iy < count_1; iy++)
            {
                double ty = 1.0 * iy / count_1;
                double y  = env.ymin * (1.0 - ty) + ty * env.ymax;
                for (int ix = 0; ix < count_1; ix++)
                {
                    double tx = 1.0 * ix / count_1;
                    double x  = env.xmin * (1.0 - tx) + tx * env.xmax;
                    com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(x, y);
                    com.epl.geometry.PolygonUtils.PiPResult       res = com.epl.geometry.PolygonUtils.IsPointInPolygon2D(poly, new com.epl.geometry.Point2D(x, y), 0);
                    if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPInside)
                    {
                        bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside);
                        if (!bgood)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                        {
                            bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside);
                            if (!bgood)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border);
                            if (!bgood)
                            {
                                return(false);
                            }
                        }
                    }
                }
            }
            return(true);
        }
Beispiel #28
0
        internal void StrokeDrawPolyPath(com.epl.geometry.SimpleRasterizer rasterizer, com.epl.geometry.MultiPathImpl polyPath, double tol)
        {
            com.epl.geometry.Point2D[] fan = new com.epl.geometry.Point2D[4];
            for (int i = 0; i < fan.Length; i++)
            {
                fan[i] = new com.epl.geometry.Point2D();
            }
            com.epl.geometry.SegmentIteratorImpl segIter = polyPath.QuerySegmentIterator();
            double strokeHalfWidth = m_transform.Transform(tol) + 1.5;
            double shortSegment    = 0.25;

            com.epl.geometry.Point2D vec        = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D vecA       = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D vecB       = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D ptStart    = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D ptEnd      = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D prev_start = new com.epl.geometry.Point2D();
            com.epl.geometry.Point2D prev_end   = new com.epl.geometry.Point2D();
            double[] helper_xy_10_elm           = new double[10];
            com.epl.geometry.Envelope2D segEnv  = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Point2D    ptOld   = new com.epl.geometry.Point2D();
            while (segIter.NextPath())
            {
                bool hasFan = false;
                bool first  = true;
                ptOld.SetCoords(0, 0);
                while (segIter.HasNextSegment())
                {
                    com.epl.geometry.Segment seg = segIter.NextSegment();
                    ptStart.x = seg.GetStartX();
                    ptStart.y = seg.GetStartY();
                    ptEnd.x   = seg.GetEndX();
                    ptEnd.y   = seg.GetEndY();
                    segEnv.SetEmpty();
                    segEnv.Merge(ptStart.x, ptStart.y);
                    segEnv.MergeNE(ptEnd.x, ptEnd.y);
                    if (!m_geomEnv.IsIntersectingNE(segEnv))
                    {
                        if (hasFan)
                        {
                            rasterizer.StartAddingEdges();
                            rasterizer.AddSegmentStroke(prev_start.x, prev_start.y, prev_end.x, prev_end.y, strokeHalfWidth, false, helper_xy_10_elm);
                            rasterizer.RenderEdges(com.epl.geometry.SimpleRasterizer.EVEN_ODD);
                            hasFan = false;
                        }
                        first = true;
                        continue;
                    }
                    m_transform.Transform(ptEnd, ptEnd);
                    if (first)
                    {
                        m_transform.Transform(ptStart, ptStart);
                        ptOld.SetCoords(ptStart);
                        first = false;
                    }
                    else
                    {
                        ptStart.SetCoords(ptOld);
                    }
                    prev_start.SetCoords(ptStart);
                    prev_end.SetCoords(ptEnd);
                    rasterizer.StartAddingEdges();
                    hasFan = !rasterizer.AddSegmentStroke(prev_start.x, prev_start.y, prev_end.x, prev_end.y, strokeHalfWidth, true, helper_xy_10_elm);
                    rasterizer.RenderEdges(com.epl.geometry.SimpleRasterizer.EVEN_ODD);
                    if (!hasFan)
                    {
                        ptOld.SetCoords(prev_end);
                    }
                }
                if (hasFan)
                {
                    rasterizer.StartAddingEdges();
                    hasFan = !rasterizer.AddSegmentStroke(prev_start.x, prev_start.y, prev_end.x, prev_end.y, strokeHalfWidth, false, helper_xy_10_elm);
                    rasterizer.RenderEdges(com.epl.geometry.SimpleRasterizer.EVEN_ODD);
                }
            }
        }