/** * Defines a comparision operation on DepthSegments * which orders them left to right * * <pre> * DS1 < DS2 if DS1.seg is left of DS2.seg * DS1 > DS2 if DS1.seg is right of DS2.seg * </pre> * * @param obj * @return the comparison value */ public int CompareTo(DepthSegment other) { if (!envelopesOverlap(upwardSeg, other.upwardSeg)) { return(upwardSeg.CompareTo(other.upwardSeg)); } // check orientations int orientIndex = upwardSeg.OrientationIndex(other.upwardSeg); if (orientIndex != 0) { return(orientIndex); } orientIndex = -other.upwardSeg.OrientationIndex(upwardSeg); if (orientIndex != 0) { return(orientIndex); } // segments cross or are collinear. Use segment ordering return(upwardSeg.CompareTo(other.upwardSeg)); }
/// <summary> /// Defines a comparison operation on <see cref="DepthSegment"/>s /// which orders them left to right. /// </summary> /// <remarks> /// Assumes the segments are normalized. /// <para/> /// The definition of ordering is: /// <list type="table"> /// <item><term>-1</term><description>if DS1.seg is left of or below DS2.seg (DS1 < DS2).</description></item> /// <item><term>1</term><description>if DS1.seg is right of or above DS2.seg (DS1 > DS2).</description></item> /// <item><term>0</term><description>if the segments are identical</description></item> /// </list> /// Known Bugs: /// <list type="bullet"> /// <item><description>The logic does not obey the <see cref="IComparable.CompareTo"/> contract. /// This is acceptable for the intended usage, but may cause problems if used with some /// utilities in the .Net standard library (e.g. <see cref="T:System.Collections.List.Sort()"/>.</description></item> /// </list> /// </remarks> /// <param name="other">A DepthSegment</param> /// <returns>The comparison value</returns> public int CompareTo(DepthSegment other) { // fast check if segments are trivially ordered along X if (_upwardSeg.MinX >= other._upwardSeg.MaxX) { return(1); } if (_upwardSeg.MaxX <= other._upwardSeg.MinX) { return(-1); } /* * 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 (orientIndex != 0) { return(orientIndex); } /* * If comparison between this and other is indeterminate, * try the opposite call order. * The sign of the result needs to be flipped */ orientIndex = -1 * other._upwardSeg.OrientationIndex(_upwardSeg); if (orientIndex != 0) { return(orientIndex); } // otherwise, use standard lexicographic segment ordering return(_upwardSeg.CompareTo(other._upwardSeg)); }