/// <summary>
        ///  simple_Polygon(): test if a Polygon is simple or not
        ///     Input:  Pn = a polygon with n vertices V[]
        ///     Return: false(0) = is NOT simple
        ///             true(1)  = IS simple
        /// </summary>
        /// <param name="polygon"></param>
        /// <returns></returns>
        public bool IsSimple(Polygon polygon)
        {
            Require.ArgumentNotNull(polygon, nameof(polygon));

            EventQueue eventQueue = new EventQueue(polygon);
            SweepLine  sweepLine  = new SweepLine(polygon);
            Event      currentEvent;                         // the current event

            // This loop processes all events in the sorted queue
            // Events are only left or right vertices since
            // No new events will be added (an intersect => Done)
            while ((currentEvent = eventQueue.Next()) != null)
            {
                // while there are events
                if (currentEvent.EventType == EventType.Left)
                {                                                     // process a left vertex
                    var currentSegment = sweepLine.Add(currentEvent); // add it to the sweep line
                    if (sweepLine.Intersect(currentSegment, currentSegment.Above))
                    {
                        return(false);                             // Pn is NOT simple
                    }
                    if (sweepLine.Intersect(currentSegment, currentSegment.Below))
                    {
                        return(false);                             // Pn is NOT simple
                    }
                }
                else
                {                                      // processs a right vertex
                    var currentSegment = sweepLine.Find(currentEvent);
                    if (sweepLine.Intersect(currentSegment.Above, currentSegment.Below))
                    {
                        return(false);                             // Pn is NOT simple
                    }
                    sweepLine.Remove(currentSegment);              // remove it from the sweep line
                }
            }
            return(true);                 // Pn IS simple
        }
Exemplo n.º 2
0
        /// <summary>
        /// Computes whether one or more line strings specified by coordinates intersects with each other.
        /// </summary>
        public void Compute()
        {
            // source: http://geomalgorithms.com/a09-_intersect-3.html

            EndPointEvent    e = _eventQueue.Next();
            SweepLineSegment segment;

            while (e != null)
            {
                switch (e.Type)
                {
                case EventType.Left:
                    segment = _sweepLine.Add(e);
                    if (segment.Above != null && _sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) && segment.LeftCoordinate == segment.Above.LeftCoordinate)
                    {
                        _sweepLine.Intersect(segment, segment.Above);
                    }
                    else if (segment.Below != null && _sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) && segment.LeftCoordinate == segment.Below.LeftCoordinate)
                    {
                        _sweepLine.Intersect(segment, segment.Below);
                    }

                    if (segment.Above != null && !_sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) &&
                        LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate,
                                                  segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                  PrecisionModel))
                    {
                        _hasResult = true;
                        _result    = true;
                        return;
                    }
                    if (segment.Below != null && !_sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) &&
                        LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate,
                                                  segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                  PrecisionModel))
                    {
                        _hasResult = true;
                        _result    = true;
                        return;
                    }
                    break;

                case EventType.Right:
                    segment = _sweepLine.Search(e);
                    if (segment != null)
                    {
                        if (segment.Above != null && segment.Below != null && !_sweepLine.IsAdjacent(segment.Below.Edge, segment.Above.Edge) &&
                            LineAlgorithms.Intersects(segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                      segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                      PrecisionModel))
                        {
                            _hasResult = true;
                            _result    = true;
                            return;
                        }
                        _sweepLine.Remove(segment);
                    }
                    break;
                }

                e = _eventQueue.Next();
            }

            _hasResult = true;
            _result    = false;
        }