/// <summary> /// Defines a comparision operation on DepthSegments /// which orders them left to right: /// DS1 smaller DS2 if DS1.seg is left of DS2.seg. /// DS1 bigger DS2 if DS1.seg is right of DS2.seg. /// </summary> /// <param name="obj"></param> /// <returns></returns> public int CompareTo(Object obj) { DepthSegment other = (DepthSegment)obj; /* * try and compute a determinate orientation for the segments. * Test returns 1 if other is left of this (i.e. this > other) */ int orientIndex = upwardSeg.OrientationIndex(other.upwardSeg); /* * If comparison between this and other is indeterminate, * try the opposite call order. * orientationIndex value is 1 if this is left of other, * so have to flip sign to get proper comparison value of * -1 if this is leftmost */ if (orientIndex == 0) { orientIndex = -1 * other.upwardSeg.OrientationIndex(upwardSeg); } // if orientation is determinate, return it if (orientIndex != 0) { return(orientIndex); } // otherwise, segs must be collinear - sort based on minimum X value return(CompareX(this.upwardSeg, other.upwardSeg)); }
private static bool IsSymmetric(DepthSegment seg1, DepthSegment seg2) { int cmp12 = seg1.CompareTo(seg2); int cmp21 = seg2.CompareTo(seg1); return(cmp12 == -cmp21); }
/// <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> /// /// </summary> /// <param name="p"></param> /// <returns></returns> public int GetDepth(ICoordinate p) { ArrayList stabbedSegments = new ArrayList(FindStabbedSegments(p)); // if no segments on stabbing line subgraph must be outside all others. if (stabbedSegments.Count == 0) { return(0); } stabbedSegments.Sort(); DepthSegment ds = (DepthSegment)stabbedSegments[0]; return(ds.LeftDepth); }
private bool IsTransitive(DepthSegment seg1, DepthSegment seg2, DepthSegment seg3) { int cmp12 = seg1.CompareTo(seg2); int cmp23 = seg2.CompareTo(seg3); int cmp13 = seg1.CompareTo(seg3); if (cmp12 > 0 && cmp23 > 0) { if (cmp13 <= 0) { Console.WriteLine(seg1 + " " + seg2 + " " + seg3); return(false); } } return(true); }
/// <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 stabbedSegments) { IList<Coordinate> 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) == CgAlgorithms.RIGHT) continue; // stabbing line cuts this segment, so record it int depth = dirEdge.GetDepth(PositionType.Left); // if segment direction was flipped, use RHS depth instead if (!_seg.P0.Equals(pts[i])) depth = dirEdge.GetDepth(PositionType.Right); DepthSegment ds = new DepthSegment(_seg, depth); stabbedSegments.Add(ds); } }