private void checkIntersection(Event upper,Event lower, OrderedSet<Event> Q,List<Point> outPoints) { Line a = new Line(upper.point,segments[upper.segIdx].End); Line b = new Line(lower.point,segments[lower.segIdx].End); if (HelperMethods.CheckTurn(new Line(a.Start, a.End), b.Start) == HelperMethods.CheckTurn(new Line(a.Start, a.End), b.End) || (HelperMethods.CheckTurn(new Line(b.Start, b.End), a.Start) == HelperMethods.CheckTurn(new Line(b.Start, b.End), a.End))) return; double aa, bb, cc, dd; Point interPoint; if (Math.Abs(a.Start.X - a.End.X) < Constants.Epsilon) { bb = (b.Start.Y - b.End.Y) / (b.Start.X - b.End.X); dd = b.Start.Y - b.Start.X * bb; interPoint = new Point(a.Start.X, (bb * a.Start.X + dd)); } else if (Math.Abs(b.Start.X - b.End.X) < Constants.Epsilon) { aa = (a.Start.Y - a.End.Y) / (a.Start.X - a.End.X); cc = a.Start.Y - a.Start.X * aa; interPoint = new Point(b.Start.X, (aa * a.Start.X + cc)); } else { aa = (a.Start.Y - a.End.Y) / (a.Start.X - a.End.X); bb = (b.Start.Y - b.End.Y) / (b.Start.X - b.End.X); cc = a.Start.Y - a.Start.X * aa; dd = b.Start.Y - b.Start.X * bb; double interX = (dd - cc) / (aa - bb); interPoint = new Point(interX, (aa * interX + cc)); } Q.Add(new Event(interPoint, PointType.Intersection,-1 ,upper,lower)); outPoints.Add(interPoint); }
public Event(Point p, PointType type, int sIdx,Event _upper,Event _lower) { point = p; pType = type; segIdx = sIdx; upper = _upper; lower = _lower; }
private double lineVal(Event line, double x) { Line a= segments[line.segIdx]; if(Math.Abs(a.Start.X-a.End.X)<Constants.Epsilon) return double.MaxValue; double m = (a.End.Y - a.Start.Y)/ (a.End.X - a.Start.X); double c = a.Start.Y - (a.Start.X * m); return x * m + c; }
private void handleEvent(Event curEvent, OrderedSet<Event> L, OrderedSet<Event> Q, List<Point> outPoints) { switch (curEvent.pType) { case PointType.Start: { KeyValuePair<Event, Event> upLow = L.DirectUpperAndLower(curEvent); if (upLow.Key != null) checkIntersection(upLow.Key, curEvent, Q, outPoints); if (upLow.Value != null) checkIntersection(curEvent, upLow.Value, Q, outPoints); L.Add(curEvent); break; } case PointType.End: { KeyValuePair<Event, Event> upLow = L.DirectUpperAndLower(curEvent); if (upLow.Key != null && upLow.Value != null) checkIntersection(upLow.Key, upLow.Value, Q, outPoints); L.Remove(new Event(segments[curEvent.segIdx].Start, PointType.Start, curEvent.segIdx, null, null)); break; } case PointType.Intersection: { Event upup = L.DirectUpperAndLower(curEvent.upper).Key; Event lowlow = L.DirectUpperAndLower(curEvent.lower).Value; if (upup !=null) checkIntersection(upup, curEvent.lower, Q, outPoints); if (lowlow != null) checkIntersection(curEvent.upper,lowlow, Q, outPoints); L.Remove(curEvent.upper); L.Remove(curEvent.lower); curEvent.lower.point.X = curEvent.point.X;curEvent.lower.point.Y = curEvent.point.Y; curEvent.upper.point.X = curEvent.point.X; curEvent.upper.point.Y = curEvent.point.Y; L.Add(curEvent.upper); L.Add(curEvent.lower); break; } default: break; } }
private int comparerEventY(Event x, Event y) { if (x.pType == PointType.Start && y.pType == PointType.Start && x.segIdx == y.segIdx) return 0; if (x.point.Equals(y.point)) { if(segments[x.segIdx].End.Equals(segments[y.segIdx].End)) return 0; double maxEX = Math.Max(segments[x.segIdx].End.X, segments[y.segIdx].End.X); return lineVal(x, maxEX) < lineVal(y, maxEX) ? -1 : 1; } double maxSX = Math.Max(x.point.X, y.point.X); return lineVal(x, maxSX) < lineVal(y, maxSX) ? -1 : 1; }
private int comparerEventX(Event x, Event y) { if (x.pType == PointType.Start && y.pType == PointType.Start && x.segIdx == y.segIdx) return 0; if (x.point.Equals(y.point)) return 0; if (Math.Abs(x.point.X - y.point.X) < Constants.Epsilon) return x.point.Y < y.point.Y ? -1 : 1; return x.point.X < y.point.X ? -1 : 1; }