internal RBNode <ScanSegment> FindLowestIntersectorNode(Point start, Point end) { Debug.Assert(ScanDirection.IsPerpendicular(start, end), "non-perpendicular segment passed"); // Find the last segment that starts at or before 'start'. this.lookupSegment.Update(start, start); RBNode <ScanSegment> node = this.segmentTree.FindLast(this.findIntersectorPred); // We have a segment that intersects start/end, or one that ends before 'start' and thus we // must iterate to find the lowest bisector. TODOperf: see how much that iteration costs us // (here and Highest); consider a BSP tree or interval tree (maybe 2-d RBTree for updatability). if (PointComparer.Equal(start, end)) { if ((null != node) && (ScanDirection.Compare(node.Item.End, start) < 0)) { node = null; } } else { this.lookupSegment.Update(start, end); while ((null != node) && !node.Item.IntersectsSegment(this.lookupSegment)) { // If the node segment starts after 'end', no intersection was found. if (ScanDirection.Compare(node.Item.Start, end) > 0) { return(null); } node = this.segmentTree.Next(node); } } return(node); }
// Find the highest perpendicular scanseg that intersects the segment endpoints. internal ScanSegment FindHighestIntersector(Point start, Point end) { Debug.Assert(ScanDirection.IsPerpendicular(start, end), "non-perpendicular segment passed"); // Find the last segment that starts at or before 'end'. this.lookupSegment.Update(end, end); RBNode <ScanSegment> node = this.segmentTree.FindLast(this.findIntersectorPred); // Now we either have a segment that intersects start/end, or one that ends before // 'end' and need to iterate to find the highest bisector. if (PointComparer.Equal(start, end)) { if ((null != node) && (ScanDirection.Compare(node.Item.End, start) < 0)) { node = null; } } else { this.lookupSegment.Update(start, end); while ((null != node) && !node.Item.IntersectsSegment(this.lookupSegment)) { // If the node segment ends before 'start', no intersection was found. if (ScanDirection.Compare(node.Item.End, start) < 0) { return(null); } node = this.segmentTree.Previous(node); } } return((null != node) ? node.Item : null); }
internal BasicObstacleSide(Obstacle obstacle, PolylinePoint startVertex, ScanDirection scanDir, bool traverseClockwise) : base(startVertex) { Obstacle = obstacle; endVertex = traverseClockwise ? startVertex.NextOnPolyline : startVertex.PrevOnPolyline; if (!scanDir.IsPerpendicular(startVertex.Point, endVertex.Point)) { Slope = StaticGraphUtility.Slope(startVertex.Point, endVertex.Point, scanDir); SlopeInverse = 1.0 / Slope; } }
internal BasicObstacleSide(Obstacle obstacle, PolylinePoint startVertex, ScanDirection scanDir, bool traverseClockwise) : base(startVertex) { Obstacle = obstacle; endVertex = traverseClockwise ? startVertex.NextOnPolyline : startVertex.PrevOnPolyline; if (!scanDir.IsPerpendicular(startVertex.Point, endVertex.Point)) { Slope = StaticGraphUtility.Slope(startVertex.Point, endVertex.Point, scanDir); SlopeInverse = 1.0 / Slope; } }
internal ScanSegment Find(Point start, Point end) { Debug.Assert(PointComparer.Equal(start, end) || !ScanDirection.IsPerpendicular(start, end) , "perpendicular segment passed"); this.lookupSegment.Update(start, end); RBNode <ScanSegment> node = this.segmentTree.Find(this.lookupSegment); if ((null != node) && PointComparer.Equal(node.Item.End, end)) { return(node.Item); } return(null); }