void ProcessEvent(SweepEvent p) { var vertexEvent = p as VertexEvent; // ShowTrees(CurveFactory.CreateDiamond(3, 3, p.Site)); if (vertexEvent != null) ProcessVertexEvent(vertexEvent); else { var rightIntersectionEvent = p as RightIntersectionEvent; if (rightIntersectionEvent != null) ProcessRightIntersectionEvent(rightIntersectionEvent); else { var leftIntersectionEvent = p as LeftIntersectionEvent; if (leftIntersectionEvent != null) ProcessLeftIntersectionEvent(leftIntersectionEvent); else { var coneClosure = p as ConeClosureEvent; if (coneClosure != null) { if (!coneClosure.ConeToClose.Removed) RemoveCone(coneClosure.ConeToClose); } else { var portLocationEvent = p as PortLocationEvent; if (portLocationEvent != null) ProcessPortLocationEvent(portLocationEvent); else ProcessPointObstacleEvent((PortObstacleEvent) p); } Z = GetZ(p); } } } // ShowTrees(CurveFactory.CreateEllipse(3,3,p.Site)); }
protected virtual void ProcessCustomEvent(SweepEvent evt) { // These are events specific to the derived class; by default there are none. Debug.Assert(false, "Unknown event type"); }
// static int count; void GoOverConesSeeingVertexEvent(SweepEvent vertexEvent) { RBNode <ConeSide> rbNode = FindFirstSegmentInTheRightTreeNotToTheLeftOfVertex(vertexEvent); if (rbNode == null) { return; } ConeSide coneRightSide = rbNode.Item; Cone cone = coneRightSide.Cone; ConeSide leftConeSide = cone.LeftSide; if (VertexIsToTheLeftOfSegment(vertexEvent, leftConeSide)) { return; } var visibleCones = new List <Cone> { cone }; coneSideComparer.SetOperand(leftConeSide); rbNode = leftConeSides.Find(leftConeSide); if (rbNode == null) { double tmpZ = Z; Z = Math.Max(GetZ(leftConeSide.Start), PreviousZ); //we need to return to the past when the order was still correct coneSideComparer.SetOperand(leftConeSide); rbNode = leftConeSides.Find(leftConeSide); Z = tmpZ; #if TEST_MSAGL if (rbNode == null) { //GeometryGraph gg = CreateGraphFromObstacles(); //gg.Save("c:\\tmp\\bug"); PrintOutLeftSegTree(); Console.WriteLine(leftConeSide); ShowLeftTree(new Ellipse(3, 3, vertexEvent.Site)); ShowRightTree(new Ellipse(3, 3, vertexEvent.Site)); } #endif } rbNode = leftConeSides.Next(rbNode); while (rbNode != null && !VertexIsToTheLeftOfSegment(vertexEvent, rbNode.Item)) { visibleCones.Add(rbNode.Item.Cone); rbNode = leftConeSides.Next(rbNode); } //Show(new Ellipse(1, 1, vertexEvent.Site)); foreach (Cone c in visibleCones) { AddEdge(c.Apex, vertexEvent.Site); RemoveCone(c); } }
static Ellipse EllipseOnVert(SweepEvent vertexEvent) { // ReSharper restore UnusedMember.Local return(new Ellipse(2, 2, vertexEvent.Site)); }
RBNode <ConeSide> FindFirstSegmentInTheRightTreeNotToTheLeftOfVertex(SweepEvent vertexEvent) { return(rightConeSides.FindFirst( s => !VertexIsToTheRightOfSegment(vertexEvent, s) )); }
static bool VertexIsToTheRightOfSegment(SweepEvent vertexEvent, ConeSide seg) { return(Point.GetTriangleOrientation(seg.Start, seg.Start + seg.Direction, vertexEvent.Site) == TriangleOrientation.Clockwise); }
// Return value is whether or not we added a new segment. bool AddSegment(Point start, Point end, Obstacle eventObstacle , BasicObstacleSide lowNborSide, BasicObstacleSide highNborSide , SweepEvent action, double weight) { DevTraceInfoVgGen(1, "Adding Segment [{0} -> {1} {2}] weight {3}", start, end, weight); DevTraceInfoVgGen(2, " side {0}", lowNborSide); DevTraceInfoVgGen(2, " -> side {0}", highNborSide); if (PointComparer.Equal(start, end)) { return false; } // See if the new segment subsumes or can be subsumed by the last one. gbcList may be null. PointAndCrossingsList gbcList = CurrentGroupBoundaryCrossingMap.GetOrderedListBetween(start, end); bool extendStart, extendEnd; bool wasSubsumed = ScanSegment.Subsume(ref hintScanSegment, start, end, weight, gbcList, ScanDirection , ParallelScanSegments, out extendStart, out extendEnd); if (!wasSubsumed) { Debug.Assert((weight != ScanSegment.ReflectionWeight) || (ParallelScanSegments.Find(start, end) == null), "Reflection segments already in the ScanSegmentTree should should have been detected before calling AddSegment"); hintScanSegment = ParallelScanSegments.InsertUnique(new ScanSegment(start, end, weight, gbcList)).Item; } else if (weight == ScanSegment.ReflectionWeight) { // Do not continue this; it is probably a situation where a side is at a tiny angle from the axis, // resulting in an initial reflection segment that is parallel and very close to the extreme-vertex-derived // segment, so as the staircase progresses they eventually converge due to floating-point rounding. // See RectilinearFilesTest.ReflectionStaircasesConverge. return false; } // Do reflections only if the new segment is not overlapped. if (ScanSegment.OverlappedWeight != weight) { // If these fire, it's probably an indication that isOverlapped is not correctly set // and one of the neighbors is an OverlapSide from CreateScanSegments. Debug.Assert(lowNborSide is HighObstacleSide, "lowNbor is not HighObstacleSide"); Debug.Assert(highNborSide is LowObstacleSide, "highNbor is not LowObstacleSide"); // If we are closing the obstacle then the initial Obstacles of the reflections (the ones it // will bounce between) are the opposite neighbors. Otherwise, the OpenVertexEvent obstacle // is the ReflectionEvent initial obstacle. if (action is CloseVertexEvent) { // If both neighbor sides reflect upward, they can't intersect, so we don't need // to store a lookahead site (if neither reflect upward, StoreLookaheadSite no-ops). if (!SideReflectsUpward(lowNborSide) || !SideReflectsUpward(highNborSide)) { // Try to store both; only one will "take" (for the upward-reflecting side). // The initial Obstacle is the opposite neighbor. if (extendStart) { this.StoreLookaheadSite(highNborSide.Obstacle, lowNborSide, start, wantExtreme:false); } if (extendEnd) { this.StoreLookaheadSite(lowNborSide.Obstacle, highNborSide, end, wantExtreme: false); } } } else { if (extendStart) { StoreLookaheadSite(eventObstacle, LowNeighborSides.GroupSideInterveningBeforeLowNeighbor, lowNborSide, start); } if (extendEnd) { StoreLookaheadSite(eventObstacle, HighNeighborSides.GroupSideInterveningBeforeHighNeighbor, highNborSide, end); } } } DevTraceInfoVgGen(2, "HintScanSegment {0}{1}", hintScanSegment, wasSubsumed ? " (subsumed)" : ""); DevTrace_DumpScanSegmentsDuringAdd(3); return true; }
void CreateConeOnVertex(SweepEvent sweepEvent) { var cone = new Cone(sweepEvent.Site, this); #if SHARPKIT //http://code.google.com/p/sharpkit/issues/detail?id=368 //SharpKit/Colin - property assignment values not retained cone.LeftSide = new ConeLeftSide(cone); cone.RightSide = new ConeRightSide(cone); var leftNode = InsertToTree(leftConeSides, cone.LeftSide); var rightNode = InsertToTree(rightConeSides, cone.RightSide); #else var leftNode = InsertToTree(leftConeSides, cone.LeftSide = new ConeLeftSide(cone)); var rightNode = InsertToTree(rightConeSides, cone.RightSide = new ConeRightSide(cone)); #endif LookForIntersectionWithConeRightSide(rightNode); LookForIntersectionWithConeLeftSide(leftNode); }
static Ellipse EllipseOnVert(SweepEvent vertexEvent) { // ReSharper restore UnusedMember.Local return new Ellipse(5, 5, vertexEvent.Site); }
void ProcessEvent(SweepEvent p) { // if(debug && (p.Site-new Point(-313.122 ,-170.6)).Length<1) // Show( EllipseOnVert(p)); var vertexEvent = p as VertexEvent; if (vertexEvent != null) ProcessVertexEvent(vertexEvent); else { var rightIntersectionEvent = p as RightIntersectionEvent; if (rightIntersectionEvent != null) ProcessRightIntersectionEvent(rightIntersectionEvent); else { var leftIntersectionEvent = p as LeftIntersectionEvent; if (leftIntersectionEvent != null) ProcessLeftIntersectionEvent(leftIntersectionEvent); else { var coneClosure = p as ConeClosureEvent; if (coneClosure != null) { if (!coneClosure.ConeToClose.Removed) RemoveCone(coneClosure.ConeToClose); } else ProcessPortObstacleEvent((PortObstacleEvent)p); Z = GetZ(p); } } } //Debug.Assert(TreesAreCorrect()); }
RBNode<ConeSide> FindFirstSegmentInTheRightTreeNotToTheLeftOfVertex(SweepEvent vertexEvent) { return rightConeSides.FindFirst( s => !VertexIsToTheRightOfSegment(vertexEvent, s) ); }
static bool VertexIsToTheRightOfSegment(SweepEvent vertexEvent, ConeSide seg) { return (Point.GetTriangleOrientation(seg.Start, seg.Start + seg.Direction, vertexEvent.Site) == TriangleOrientation.Clockwise); }
// static int count; void GoOverConesSeeingVertexEvent(SweepEvent vertexEvent) { var rbNode = FindFirstSegmentInTheRightTreeNotToTheLeftOfVertex(vertexEvent); if (rbNode == null) return; var coneRightSide = rbNode.Item; var cone = coneRightSide.Cone; var leftConeSide = cone.LeftSide; if (VertexIsToTheLeftOfSegment(vertexEvent, leftConeSide)) return; var visibleCones = new List<Cone> { cone }; coneSideComparer.SetOperand(leftConeSide); rbNode = leftConeSides.Find(leftConeSide); if (rbNode == null) { var tmpZ = Z; Z = Math.Max(GetZ(leftConeSide.Start), PreviousZ); //we need to return to the past a little bit when the order was still correct coneSideComparer.SetOperand(leftConeSide); rbNode = leftConeSides.Find(leftConeSide); Z = tmpZ; #if TEST_MSAGL // if (rbNode == null) { //GeometryGraph gg = CreateGraphFromObstacles(); //gg.Save("c:\\tmp\\bug"); // PrintOutLeftSegTree(); // Console.WriteLine(leftConeSide); // ShowLeftTree(new Ellipse(3, 3, vertexEvent.Site)); // ShowRightTree(new Ellipse(3, 3, vertexEvent.Site)); // } #endif } // the following should not happen if the containment hierarchy is correct. // If containment is not correct it still should not result in a fatal error, just a funny looking route. // Debug.Assert(rbNode!=null); if (rbNode == null) {//it is an emergency measure and should not happen rbNode = GetRbNodeEmergency(rbNode, leftConeSide); } if (rbNode == null) return; // the cone is not there! and it is a bug rbNode = leftConeSides.Next(rbNode); while (rbNode != null && !VertexIsToTheLeftOfSegment(vertexEvent, rbNode.Item)) { visibleCones.Add(rbNode.Item.Cone); rbNode = leftConeSides.Next(rbNode); } //Show(new Ellipse(1, 1, vertexEvent.Site)); foreach (var visCone in visibleCones) AddEdgeAndRemoveCone(visCone, vertexEvent.Site); }
// static int count; void GoOverConesSeeingVertexEvent(SweepEvent vertexEvent) { RBNode<ConeSide> rbNode = FindFirstSegmentInTheRightTreeNotToTheLeftOfVertex(vertexEvent); if (rbNode == null) return; ConeSide coneRightSide = rbNode.Item; Cone cone = coneRightSide.Cone; ConeSide leftConeSide = cone.LeftSide; if (VertexIsToTheLeftOfSegment(vertexEvent, leftConeSide)) return; var visibleCones = new List<Cone> {cone}; coneSideComparer.SetOperand(leftConeSide); rbNode = leftConeSides.Find(leftConeSide); if (rbNode == null) { double tmpZ = Z; Z = Math.Max(GetZ(leftConeSide.Start), PreviousZ); //we need to return to the past when the order was still correct coneSideComparer.SetOperand(leftConeSide); rbNode = leftConeSides.Find(leftConeSide); Z = tmpZ; #if TEST_MSAGL if (rbNode == null) { //GeometryGraph gg = CreateGraphFromObstacles(); //gg.Save("c:\\tmp\\bug"); PrintOutLeftSegTree(); Console.WriteLine(leftConeSide); ShowLeftTree(new Ellipse(3, 3, vertexEvent.Site)); ShowRightTree(new Ellipse(3, 3, vertexEvent.Site)); } #endif } rbNode = leftConeSides.Next(rbNode); while (rbNode != null && !VertexIsToTheLeftOfSegment(vertexEvent, rbNode.Item)) { visibleCones.Add(rbNode.Item.Cone); rbNode = leftConeSides.Next(rbNode); } //Show(new Ellipse(1, 1, vertexEvent.Site)); foreach (Cone c in visibleCones) { AddEdge(c.Apex, vertexEvent.Site); RemoveCone(c); } }
void CreateConeOnPortLocation(SweepEvent sweepEvent) { var cone = new Cone(sweepEvent.Site, this); RBNode<ConeSide> leftNode = InsertToTree(leftConeSides, cone.LeftSide = new ConeLeftSide(cone)); RBNode<ConeSide> rightNode = InsertToTree(rightConeSides, cone.RightSide = new ConeRightSide(cone)); LookForIntersectionWithConeRightSide(rightNode); LookForIntersectionWithConeLeftSide(leftNode); }