/// <summary> /// Construct a new ring which is cloned from the given <paramref name="source"/> ring. /// </summary> /// <param name="source">The source ring to clone.</param> public Ring2(Ring2 source) : this( null == source ? default(bool?) : source._hole, null == source ? null : new List <Point2>(source) ) { }
/// <summary> /// Determines if two rings are spatially equal. /// </summary> /// <param name="other">Another ring to compare.</param> /// <returns>true when the given ring is spatially equal to this ring.</returns> public bool SpatiallyEqual(Ring2 other) { if (ReferenceEquals(null, other)) { return(false); } if (Equals(other)) { return(true); } if (GetMbr() != other.GetMbr()) { return(false); } if (DetermineWinding() != other.DetermineWinding()) { return(false); } if (!Hole.HasValue && other.Hole.HasValue || Hole.HasValue && !other.Hole.HasValue) { if (DetermineWinding() != other.DetermineWinding()) { return(false); } } else { if (FillSide != other.FillSide) { return(false); } } // TODO: MUST OPTIMIZE THIS GARBAGE if (!AllPointsOnBoundary(this, other)) { return(false); } if (!AllPointsOnBoundary(other, this)) { return(false); } return(true); }
private static bool AllPointsOnBoundary(Ring2 points, Ring2 boundary) { Contract.Requires(points != null); Contract.Requires(boundary != null); int segmentCount = boundary.SegmentCount; if (segmentCount == 0) { if (boundary.Count == 0) { return(points.Count == 0); } if (boundary.Count == 1) { return(points.All(p => p.Equals(boundary[0]))); } } if (segmentCount == 1 || segmentCount == 2) { var s = boundary.GetSegment(0); return(points.All(s.Intersects)); } int indexHint = 0; foreach (var p in points) { int i = indexHint; var ok = false; do { Contract.Assume(segmentCount == boundary.SegmentCount); Contract.Assume(i >= 0 && i < boundary.SegmentCount); if (boundary.GetSegment(i).Intersects(p)) { indexHint = i; ok = true; break; } i = Utility.IterationUtils.AdvanceLoopingIndex(i, segmentCount); } while (i != indexHint); if (!ok) { return(false); } } return(true); }
/// <summary> /// Indicates whether the current object is equal to another object of the same type. /// </summary> /// <returns> /// <c>true</c> if the current object is equal to the <paramref name="other"/> parameter; otherwise, <c>false</c>. /// </returns> /// <param name="other">An object to compare with this object.</param> public bool Equals(Ring2 other) { if (ReferenceEquals(null, other)) { return(false); } if (ReferenceEquals(this, other)) { return(true); } if (Count != other.Count || !_hole.Equals(other._hole)) { return(false); } for (var i = 0; i < _pointList.Count; i++) { if (!_pointList[i].Equals(other[i])) { return(false); } } return(true); }
/// <summary> /// Determines if this ring is within the given ring. /// </summary> /// <param name="testContainer">The ring to test with.</param> /// <returns>true if this ring is within the other ring.</returns> internal bool NonIntersectingWithin(Ring2 testContainer) { Contract.Ensures(testContainer != null || !Contract.Result <bool>()); if (testContainer == null) { return(false); } var thisMbr = GetMbr(); if (thisMbr == null) { return(false); } var containerMbr = testContainer.GetMbr(); if (containerMbr == null) { return(false); } var notEqual = !thisMbr.Equals(containerMbr); var bestResultGuess = notEqual; if (testContainer.Hole.HasValue && testContainer.Hole.Value) { if (thisMbr.Intersects(containerMbr)) { if (notEqual) { if (thisMbr.Contains(containerMbr)) { bestResultGuess = true; } else if (containerMbr.Contains(thisMbr)) { bestResultGuess = false; } } } else { return(true); } } else { if (thisMbr.Intersects(containerMbr)) { if (notEqual) { if (thisMbr.Contains(containerMbr)) { bestResultGuess = false; } if (containerMbr.Contains(thisMbr)) { bestResultGuess = true; } } } else { return(false); } } // need to test points bool mayHaveIt = false; foreach (var p in this) { int res = testContainer.AdvancedIntersectionTest(p); if (res > 0) { return(true); } if (res < 0) { return(false); } mayHaveIt = bestResultGuess; } return(mayHaveIt); }