/// <summary> /// Computes the intersection of one or more line strings. /// </summary> public void Compute() { this.intersections = new List <Coordinate>(); this.edgeIndexes = new List <Tuple <Int32, Int32> >(); Event currentEvent = this.eventQueue.Next(); while (currentEvent != null) { EndPointEvent endPointEvent = currentEvent as EndPointEvent; if (endPointEvent != null) { this.ProcessEndPointEvent(endPointEvent); } IntersectionEvent intersectionEvent = currentEvent as IntersectionEvent; if (intersectionEvent != null) { // intersection point event: switch the two concerned segments and check for possible intersection with their below and above segments this.ProcessIntersectionEvent(intersectionEvent); } currentEvent = this.eventQueue.Next(); } this.hasResult = true; }
/// <summary> /// Computes the intersection of one or more line strings. /// </summary> public void Compute() { // source: http://geomalgorithms.com/a09-_intersect-3.html _intersections = new List <Coordinate>(); _edgeIndices = new List <Tuple <Int32, Int32> >(); Event currentEvent = _eventQueue.Next(); SweepLineSegment segment; IList <Coordinate> intersections; while (currentEvent != null) { if (currentEvent is EndPointEvent) { EndPointEvent endPointEvent = (EndPointEvent)currentEvent; switch (endPointEvent.Type) { // Left endpoint event: check for possible intersection with below and / or above segments. case EventType.Left: segment = _sweepLine.Add(endPointEvent); if (segment.Above != null) { intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Above.LeftCoordinate, segment.Above.RightCoordinate, PrecisionModel); if (intersections.Count > 0) { IntersectionEvent intersectionEvent = new IntersectionEvent { Vertex = intersections[0], Below = segment, Above = segment.Above }; _eventQueue.Add(intersectionEvent); } } if (segment.Below != null) { intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, PrecisionModel); if (intersections.Count > 0) { IntersectionEvent intersectionEvent = new IntersectionEvent { Vertex = intersections[0], Below = segment.Below, Above = segment }; _eventQueue.Add(intersectionEvent); } } break; // Right endpoint event: check for possible intersection of the below and above segments. case EventType.Right: segment = _sweepLine.Search(endPointEvent); if (segment != null) { if (segment.Above != null && segment.Below != null) { intersections = LineAlgorithms.Intersection(segment.Above.LeftCoordinate, segment.Above.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, PrecisionModel); if (intersections.Count > 0) { IntersectionEvent intersectionEvent = new IntersectionEvent { Vertex = intersections[0], Below = segment.Below, Above = segment.Above }; if (!_eventQueue.Contains(intersectionEvent)) { _eventQueue.Add(intersectionEvent); } } } _sweepLine.Remove(segment); } break; } } // Intersection point event: switch the two concerned segments and check for possible intersection with their below and above segments. else if (currentEvent is IntersectionEvent) { IntersectionEvent intersectionEvent = (IntersectionEvent)currentEvent; /* * Segment order before intersection: segmentBelow <-> segmentAbove <-> segment <-> segmentAboveAbove * Segment order after intersection: segmentBelow <-> segment <-> segmentAbove <-> segmentAboveAbove */ segment = intersectionEvent.Above; SweepLineSegment segmentAbove = intersectionEvent.Below; // Handle closing intersection points when segments (partially) overlap each other. if (intersectionEvent.IsClose) { if (!_sweepLine.IsAdjacent(segment.Edge, segmentAbove.Edge)) { _intersections.Add(currentEvent.Vertex); _edgeIndices.Add(Tuple.Create(Math.Min(segment.Edge, segmentAbove.Edge), Math.Max(segment.Edge, segmentAbove.Edge))); } } // It is possible that the previously detected intersection point is not a real intersection, because a new segment started between them, // therefore a repeated check is necessary to carry out. else if (_sweepLine.Add(intersectionEvent)) { if (!_sweepLine.IsAdjacent(segment.Edge, segmentAbove.Edge)) { _intersections.Add(currentEvent.Vertex); _edgeIndices.Add(Tuple.Create(Math.Min(segment.Edge, segmentAbove.Edge), Math.Max(segment.Edge, segmentAbove.Edge))); intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segmentAbove.LeftCoordinate, segmentAbove.RightCoordinate, PrecisionModel); if (intersections.Count > 1 && !intersections[1].Equals(intersections[0])) { IntersectionEvent newIntersectionEvent = new IntersectionEvent { Vertex = intersections[1], Below = segment, Above = segmentAbove, IsClose = true, }; _eventQueue.Add(newIntersectionEvent); } } if (segmentAbove.Above != null) { intersections = LineAlgorithms.Intersection(segmentAbove.LeftCoordinate, segmentAbove.RightCoordinate, segmentAbove.Above.LeftCoordinate, segmentAbove.Above.RightCoordinate, PrecisionModel); if (intersections.Count > 0 && intersections[0].X >= intersectionEvent.Vertex.X) { IntersectionEvent newIntersectionEvent = new IntersectionEvent { Vertex = intersections[0], Below = segmentAbove, Above = segmentAbove.Above }; if (!_eventQueue.Contains(newIntersectionEvent)) { _eventQueue.Add(newIntersectionEvent); } } } if (segment.Below != null) { intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, PrecisionModel); if (intersections.Count > 0 && intersections[0].X >= intersectionEvent.Vertex.X) { IntersectionEvent newIntersectionEvent = new IntersectionEvent { Vertex = intersections[0], Below = segment.Below, Above = segment }; if (!_eventQueue.Contains(newIntersectionEvent)) { _eventQueue.Add(newIntersectionEvent); } } } } } currentEvent = _eventQueue.Next(); } _hasResult = true; }
/// <summary> /// Processes the end point event. /// </summary> /// <param name="endPointEvent">The end point event.</param> private void ProcessEndPointEvent(EndPointEvent endPointEvent) { SweepLineSegment segment; Intersection intersection; switch (endPointEvent.Type) { // left endpoint event: check for possible intersection with below and / or above segments case EventType.Left: segment = this.sweepLine.Add(endPointEvent); if (segment.Above != null) { intersection = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Above.LeftCoordinate, segment.Above.RightCoordinate, this.PrecisionModel); if (intersection != null) { IntersectionEvent intersectionEvent = new IntersectionEvent { Vertex = intersection.Coordinate, Below = segment, Above = segment.Above }; this.eventQueue.Add(intersectionEvent); } } if (segment.Below != null) { intersection = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, this.PrecisionModel); if (intersection != null) { IntersectionEvent intersectionEvent = new IntersectionEvent { Vertex = intersection.Coordinate, Below = segment.Below, Above = segment }; this.eventQueue.Add(intersectionEvent); } } break; // right endpoint event: check for possible intersection of the below and above segments case EventType.Right: segment = this.sweepLine.Search(endPointEvent); if (segment != null) { if (segment.Above != null && segment.Below != null) { intersection = LineAlgorithms.Intersection(segment.Above.LeftCoordinate, segment.Above.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, this.PrecisionModel); if (intersection != null) { IntersectionEvent intersectionEvent = new IntersectionEvent { Vertex = intersection.Coordinate, Below = segment.Below, Above = segment.Above }; if (!this.eventQueue.Contains(intersectionEvent)) { this.eventQueue.Add(intersectionEvent); } } } this.sweepLine.Remove(segment); } break; } }
/// <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; }
/// <summary> /// Computes whether one or more line strings specified by coordinates intersects with each other. /// </summary> public void Compute() { EndPointEvent e = this.eventQueue.Next(); SweepLineSegment segment; while (e != null) { switch (e.Type) { case EventType.Left: segment = this.sweepLine.Add(e); if (segment.Above != null && this.sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) && segment.LeftCoordinate == segment.Above.LeftCoordinate) { this.sweepLine.Intersect(segment, segment.Above); } else if (segment.Below != null && this.sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) && segment.LeftCoordinate == segment.Below.LeftCoordinate) { this.sweepLine.Intersect(segment, segment.Below); } if (segment.Above != null && !this.sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) && LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate, segment.Above.LeftCoordinate, segment.Above.RightCoordinate, this.PrecisionModel)) { this.hasResult = true; this.result = true; return; } if (segment.Below != null && !this.sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) && LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, this.PrecisionModel)) { this.hasResult = true; this.result = true; return; } break; case EventType.Right: segment = this.sweepLine.Search(e); if (segment != null) { if (segment.Above != null && segment.Below != null && !this.sweepLine.IsAdjacent(segment.Below.Edge, segment.Above.Edge) && LineAlgorithms.Intersects(segment.Above.LeftCoordinate, segment.Above.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, this.PrecisionModel)) { this.hasResult = true; this.result = true; return; } this.sweepLine.Remove(segment); } break; } e = this.eventQueue.Next(); } this.hasResult = true; this.result = false; }