Exemple #1
0
 public bool Contains(Segment segment)
 {
     return (segment == Intersection(segment));
 }
Exemple #2
0
        public Segment Intersection(Segment segment)
        {
            // if either segment is empty, the intersection is also empty
            if (IsEmpty || segment.IsEmpty)
                return Segment.Empty;

            // if the segments are equal, just return a new equal segment
            if (this == segment)
                return new Segment(_p1, _p2, _isP1Excluded, _isP2Excluded);

            // if either segment is a Point, just see if the point is contained in the other segment
            if (IsPoint)
                return segment.Contains(_p1) ? new Segment(_p1) : Segment.Empty;

            if (segment.IsPoint)
                return Contains(segment._p1) ? new Segment(segment._p1) : Segment.Empty;

            // okay, no easy answer, so let's do the math...
            Point p1 = _p1;
            Vector v1 = _p2 - _p1;
            Point p2 = segment._p1;
            Vector v2 = segment._p2 - segment._p1;
            Vector endpointVector = p2 - p1;

            double xProd = Vector.CrossProduct(v1, v2);

            // if segments are not parallel, then look for intersection on each segment
            if (!DoubleHelper.AreVirtuallyEqual(Slope, segment.Slope))
            {
                // check for intersection on other segment
                double s = (Vector.CrossProduct(endpointVector, v1)) / xProd;
                if (s < 0 || s > 1)
                    return Segment.Empty;

                // check for intersection on this segment
                s = (Vector.CrossProduct(endpointVector, v2)) / xProd;
                if (s < 0 || s > 1)
                    return Segment.Empty;

                // intersection of segments is a point
                return new Segment(p1 + s * v1);
            }

            // segments are parallel
            xProd = Vector.CrossProduct(endpointVector, v1);
            if (xProd * xProd > 1.0e-06 * v1.LengthSquared * endpointVector.LengthSquared)
            {
                // segments do not intersect
                return Segment.Empty;
            }

            // intersection is overlapping segment
            Segment result = new Segment();

            // to determine the overlapping segment, create reference segments where the endpoints are *not* excluded
            Segment refThis = new Segment(_p1, _p2);
            Segment refSegment = new Segment(segment._p1, segment._p2);

            // check whether this segment is contained in the other segment
            bool includeThisP1 = refSegment.Contains(refThis._p1);
            bool includeThisP2 = refSegment.Contains(refThis._p2);
            if (includeThisP1 && includeThisP2)
            {
                result._p1 = _p1;
                result._p2 = _p2;
                result._isP1Excluded = _isP1Excluded || !segment.Contains(_p1);
                result._isP2Excluded = _isP2Excluded || !segment.Contains(_p2);
                return result;
            }

            // check whether the other segment is contained in this segment
            bool includeSegmentP1 = refThis.Contains(refSegment._p1);
            bool includeSegmentP2 = refThis.Contains(refSegment._p2);
            if (includeSegmentP1 && includeSegmentP2)
            {
                result._p1 = segment._p1;
                result._p2 = segment._p2;
                result._isP1Excluded = segment._isP1Excluded || !Contains(segment._p1);
                result._isP2Excluded = segment._isP2Excluded || !Contains(segment._p2);
                return result;
            }

            // the intersection must include one endpoint from this segment and one endpoint from the other segment
            if (includeThisP1)
            {
                result._p1 = _p1;
                result._isP1Excluded = _isP1Excluded || !segment.Contains(_p1);
            }
            else
            {
                result._p1 = _p2;
                result._isP1Excluded = _isP2Excluded || !segment.Contains(_p2);
            }
            if (includeSegmentP1)
            {
                result._p2 = segment._p1;
                result._isP2Excluded = segment._isP1Excluded || !Contains(segment._p1);
            }
            else
            {
                result._p2 = segment._p2;
                result._isP2Excluded = segment._isP2Excluded || !Contains(segment._p2);
            }
            return result;
        }
Exemple #3
0
 public static bool AreVirtuallyEqual(Segment s1, Segment s2)
 {
     // note: Segment struct already uses "virtually equal" approach
     return (s1 == s2);
 }