Exemple #1
0
 // Try to find two segements that are not degenerate
 internal virtual bool Calc_side(com.epl.geometry.Point2D inputPoint, bool bRight, com.epl.geometry.MultiPath multipath, int vertexIndex, int pathIndex)
 {
     com.epl.geometry.SegmentIterator segIter = multipath.QuerySegmentIterator();
     this.Find_analysis_pair_from_index(inputPoint, segIter, vertexIndex, pathIndex);
     if (this.m_i1 != -1 && this.m_i2 == -1)
     {
         // could not find a pair of segments
         return(this.m_bRight1);
     }
     if (this.m_i1 != -1 && this.m_i2 != -1)
     {
         if (this.m_bRight1 == this.m_bRight2)
         {
             return(this.m_bRight1);
         }
         else
         {
             // no conflicting result for the side
             // the conflicting result, that we are trying to resolve,
             // happens in the obtuse (outer) side of the turn only.
             segIter.ResetToVertex(this.m_i1, -1);
             com.epl.geometry.Segment segment1 = segIter.NextSegment();
             com.epl.geometry.Point2D tang1    = segment1._getTangent(1.0);
             segIter.ResetToVertex(this.m_i2, -1);
             com.epl.geometry.Segment segment2 = segIter.NextSegment();
             com.epl.geometry.Point2D tang2    = segment2._getTangent(0.0);
             double cross = tang1.CrossProduct(tang2);
             if (cross >= 0)
             {
                 // the obtuse angle is on the right side
                 return(true);
             }
             else
             {
                 // the obtuse angle is on the right side
                 return(false);
             }
         }
     }
     else
     {
         System.Diagnostics.Debug.Assert((this.m_i1 == -1 && this.m_i2 == -1));
         return(bRight);
     }
 }
Exemple #2
0
 internal virtual int Find_prev_non_degenerate(com.epl.geometry.SegmentIterator segIter, int index)
 {
     segIter.ResetToVertex(index, -1);
     while (segIter.HasPreviousSegment())
     {
         com.epl.geometry.Segment segment = segIter.PreviousSegment();
         double length = segment.CalculateLength2D();
         if (length != 0)
         {
             return(segIter.GetStartPointIndex());
         }
     }
     return(-1);
 }
Exemple #3
0
 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;
                 }
             }
         }
     }
 }
Exemple #4
0
        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);
        }