/// <summary> /// /// </summary> /// <param name="de"></param> private void CopySymDepths(DirectedEdge de) { DirectedEdge sym = de.Sym; sym.SetDepth(Positions.Left, de.GetDepth(Positions.Right)); sym.SetDepth(Positions.Right, de.GetDepth(Positions.Left)); }
/// <summary> /// /// </summary> /// <param name="de"></param> private static void CopySymDepths(DirectedEdge de) { var sym = de.Sym; sym.SetDepth(Position.Left, de.GetDepth(Position.Right)); sym.SetDepth(Position.Right, de.GetDepth(Position.Left)); }
private void ComputeNodeDepth(Node n, DirectedEdge startEdge) { if (startEdge.Visited) { return; } ((DirectedEdgeStar)n.Edges).ComputeDepths(startEdge); // copy depths to sym edges //for (Iterator i = ((DirectedEdgeStar) n.getEdges()).iterator(); i.hasNext(); ) foreach (object obj in n.Edges) { DirectedEdge de = (DirectedEdge)obj; // i.next(); de.Visited = true; DirectedEdge sym = de.Sym; sym.SetDepth(Position.Left, de.GetDepth(Position.Right)); sym.SetDepth(Position.Right, de.GetDepth(Position.Left)); } // propagate depth to all linked nodes via the sym edges // If a sym edge has been visited already, there is no need to process it further //for (Iterator i = ((DirectedEdgeStar) n.getEdges()).iterator(); i.hasNext(); ) foreach (object obj in n.Edges) { DirectedEdge de = (DirectedEdge)obj; DirectedEdge sym = de.Sym; Node symNode = sym.Node; // NOTE: this is a depth-first traversal of the graph. // This will cause a large depth of recursion. // It might be better to do a breadth-first traversal. ComputeNodeDepth(symNode, sym); } }
/// <summary> /// Finds all non-horizontal segments intersecting the stabbing line /// in the input dirEdge. /// The stabbing line is the ray to the right of stabbingRayLeftPt. /// </summary> /// <param name="stabbingRayLeftPt">the left-hand origin of the stabbing line /// </param> /// <param name="stabbedSegments">the current list of {@link DepthSegments} intersecting the stabbing line /// </param> private void FindStabbedSegments(Coordinate stabbingRayLeftPt, DirectedEdge dirEdge, ArrayList stabbedSegments) { ICoordinateList pts = dirEdge.Edge.Coordinates; for (int i = 0; i < pts.Count - 1; i++) { seg.p0 = pts[i]; seg.p1 = pts[i + 1]; // ensure segment always points upwards if (seg.p0.Y > seg.p1.Y) { seg.Reverse(); } // skip segment if it is left of the stabbing line double maxx = Math.Max(seg.p0.X, seg.p1.X); if (maxx < stabbingRayLeftPt.X) { continue; } // skip horizontal segments (there will be a non-horizontal one carrying the same depth info if (seg.IsHorizontal) { continue; } // skip if segment is above or below stabbing line if (stabbingRayLeftPt.Y < seg.p0.Y || stabbingRayLeftPt.Y > seg.p1.Y) { continue; } // skip if stabbing ray is right of the segment if (CGAlgorithms.ComputeOrientation(seg.p0, seg.p1, stabbingRayLeftPt) == OrientationType.Clockwise) { continue; } // stabbing line cuts this segment, so record it int depth = dirEdge.GetDepth(Position.Left); // if segment direction was flipped, use RHS depth instead if (!seg.p0.Equals(pts[i])) { depth = dirEdge.GetDepth(Position.Right); } DepthSegment ds = new DepthSegment(this, seg, depth); stabbedSegments.Add(ds); } }
/// <summary> /// Finds all non-horizontal segments intersecting the stabbing line /// in the input dirEdge. /// The stabbing line is the ray to the right of stabbingRayLeftPt. /// </summary> /// <param name="stabbingRayLeftPt">The left-hand origin of the stabbing line.</param> /// <param name="dirEdge"></param> /// <param name="stabbedSegments">The current list of DepthSegments intersecting the stabbing line.</param> private void FindStabbedSegments(Coordinate stabbingRayLeftPt, DirectedEdge dirEdge, IList <DepthSegment> stabbedSegments) { var pts = dirEdge.Edge.Coordinates; for (int i = 0; i < pts.Length - 1; i++) { _seg.P0 = pts[i]; _seg.P1 = pts[i + 1]; // ensure segment always points upwards if (_seg.P0.Y > _seg.P1.Y) { _seg.Reverse(); } // skip segment if it is left of the stabbing line double maxx = Math.Max(_seg.P0.X, _seg.P1.X); if (maxx < stabbingRayLeftPt.X) { continue; } // skip horizontal segments (there will be a non-horizontal one carrying the same depth info if (_seg.IsHorizontal) { continue; } // skip if segment is above or below stabbing line if (stabbingRayLeftPt.Y < _seg.P0.Y || stabbingRayLeftPt.Y > _seg.P1.Y) { continue; } // skip if stabbing ray is right of the segment if (Orientation.Index(_seg.P0, _seg.P1, stabbingRayLeftPt) == OrientationIndex.Right) { continue; } // stabbing line cuts this segment, so record it int depth = dirEdge.GetDepth(Positions.Left); // if segment direction was flipped, use RHS depth instead if (!_seg.P0.Equals(pts[i])) { depth = dirEdge.GetDepth(Positions.Right); } var ds = new DepthSegment(_seg, depth); stabbedSegments.Add(ds); } }
/// <summary> /// Find all edges whose depths indicates that they are in the result area(s). /// Since we want polygon shells to be oriented CW, choose dirEdges with the interior /// of the result on the RHS. Mark them as being in the result. Interior Area edges are /// the result of dimensional collapses. They do not form part of the result area boundary. /// </summary> public void FindResultEdges() { //for (Iterator it = dirEdgeList.iterator(); it.hasNext(); ) foreach (object obj in _dirEdgeList) { DirectedEdge de = (DirectedEdge)obj; // Select edges which have the EXTERIOR on the L and INTERIOR // on the right. It doesn't matter how deep the interior is. if (de.GetDepth(Position.Right) >= 1 && de.GetDepth(Position.Left) == 0 && !de.IsInteriorAreaEdge) { de.InResult = true; //Debug.print("in result "); Debug.println(de); } } }
/// <summary> /// Find all edges whose depths indicates that they are in the result area(s). /// Since we want polygon shells to be /// oriented CW, choose dirEdges with the interior of the result on the RHS. /// Mark them as being in the result. /// Interior Area edges are the result of dimensional collapses. /// They do not form part of the result area boundary. /// </summary> public void FindResultEdges() { for (IEnumerator it = dirEdgeList.GetEnumerator(); it.MoveNext();) { DirectedEdge de = (DirectedEdge)it.Current; /* * Select edges which have an interior depth on the RHS * and an exterior depth on the LHS. * Note that because of weird rounding effects there may be * edges which have negative depths! Negative depths * count as "outside". */ // <FIX> - handle negative depths if (de.GetDepth(Positions.Right) >= 1 && de.GetDepth(Positions.Left) <= 0 && !de.IsInteriorAreaEdge) { de.InResult = true; } } }