/// <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 }
/// <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; }