// Set the initial ActiveLowSide and ActiveHighSide of the obstacle starting at this point. internal void CreateInitialSides(PolylinePoint startPoint, ScanDirection scanDir) { Debug.Assert((null == ActiveLowSide) && (null == ActiveHighSide) , "Cannot call SetInitialSides when sides are already set"); ActiveLowSide = new LowObstacleSide(this, startPoint, scanDir); ActiveHighSide = new HighObstacleSide(this, startPoint, scanDir); if (scanDir.IsFlat(ActiveHighSide)) { // No flat sides in the scanline; we'll do lookahead processing in the scanline to handle overlaps // with existing segments, and normal neighbor handling will take care of collinear OpenVertexEvents. ActiveHighSide = new HighObstacleSide(this, ActiveHighSide.EndVertex, scanDir); } }
internal RBNode <BasicObstacleSide> Insert(BasicObstacleSide side, Point scanPos) { DevTraceInfo(1, "prev LinePos = {0}, new LinePos = {1}, inserting side = {2}", this.linePositionAtLastInsertOrRemove, scanPos, side.ToString()); Assert(!scanDirection.IsFlat(side), "Flat sides are not allowed in the scanline"); Assert(null == Find(side), "side already exists in the ScanLine"); this.linePositionAtLastInsertOrRemove = scanPos; // RBTree's internal operations on insert/remove etc. mean the node can't cache the // RBNode returned by insert(); instead we must do find() on each call. But we can // use the returned node to get predecessor/successor. var node = SideTree.Insert(side); DevTraceDump(2); return(node); }
internal static Point ScanLineIntersectSide(Point site, BasicObstacleSide side, ScanDirection scanDir) { // Note: we don't assert that site and side are not PointComparer.Equal, because ScanLine calls // this on sides that share vertices. Debug.Assert(!scanDir.IsFlat(side), "flat sides should not be in the scanline or encountered on lookahead scan"); // We know that we will have an intersection if the side is adjacent in the scanline, so // we can optimize the calculation to project along the slope of the BasicObstacleSide. // Also, due to rounding, we need to make sure that when intersecting the side, we're not // falling short due to rounding error; that can be a problem if we're right at a vertex // of that obstacle, because then there is no intersection with the perpendicular line // from that vertex. So make sure we are at least to the nearest coordinate of that side. // Note: Calculate slope here using 'dir' rather than side.SlopeInverse because Reflection // lookaheads calculate the perpendicular intersection and side.Slope(Inverse) is always // relative to the scanline parallel. Point dir = side.Direction; #if SHARPKIT //https://code.google.com/p/sharpkit/issues/detail?id=369 Point intersect = side.Start.Clone(); #else Point intersect = side.Start; #endif if (scanDir.IsHorizontal) { intersect.X += (dir.X / dir.Y) * (site.Y - side.Start.Y); intersect.X = SpliceUtility.MungeIntersect(site.X, intersect.X, side.Start.X, side.End.X); intersect.Y = site.Y; } else { intersect.X = site.X; intersect.Y += (dir.Y / dir.X) * (site.X - side.Start.X); intersect.Y = SpliceUtility.MungeIntersect(site.Y, intersect.Y, side.Start.Y, side.End.Y); } return intersect; }
void AssertValidSegmentForInsertion(ScanSegment seg) { Debug.Assert((seg.End.X >= seg.Start.X) && (seg.End.Y >= seg.Start.Y), "Reversed direction in ScanSegment"); Debug.Assert(ScanDirection.IsFlat(seg.Start, seg.End), "non-flat segment cannot be inserted"); }
// Set the initial ActiveLowSide and ActiveHighSide of the obstacle starting at this point. internal void CreateInitialSides(PolylinePoint startPoint, ScanDirection scanDir) { Debug.Assert((null == ActiveLowSide) && (null == ActiveHighSide) , "Cannot call SetInitialSides when sides are already set"); ActiveLowSide = new LowObstacleSide(this, startPoint, scanDir); ActiveHighSide = new HighObstacleSide(this, startPoint, scanDir); if (scanDir.IsFlat(ActiveHighSide)) { // No flat sides in the scanline; we'll do lookahead processing in the scanline to handle overlaps // with existing segments, and normal neighbor handling will take care of collinear OpenVertexEvents. ActiveHighSide = new HighObstacleSide(this, ActiveHighSide.EndVertex, scanDir); } }