Example #1
0
        private static void AdjustResultForIntersectionWithSide( ref Nullable<Point> result, ref double distance, Segment intersection, Point point )
        {
            if( !intersection.IsEmpty )
              {
            if( intersection.Contains( point ) )
            {
              distance = 0;
              result = point;
              return;
            }

            double p1Distance = PointHelper.DistanceBetween( point, intersection.P1 );
            double p2Distance = double.PositiveInfinity;
            if( !intersection.IsPoint )
            {
              p2Distance = PointHelper.DistanceBetween( point, intersection.P2 );
            }

            if( Math.Min( p1Distance, p2Distance ) < distance )
            {
              if( p1Distance < p2Distance )
              {
            distance = p1Distance;
            result = intersection.P1;
              }
              else
              {
            distance = p2Distance;
            result = intersection.P2;
              }
            }
              }
        }
Example #2
0
        public static Nullable<Point> GetNearestPointOfIntersectionBetweenRectAndSegment( Rect rect, Segment segment, Point point )
        {
            Nullable<Point> result = null;
              double distance = double.PositiveInfinity;

              Segment leftIntersection = segment.Intersection( new Segment( rect.BottomLeft, rect.TopLeft ) );
              Segment topIntersection = segment.Intersection( new Segment( rect.TopLeft, rect.TopRight ) );
              Segment rightIntersection = segment.Intersection( new Segment( rect.TopRight, rect.BottomRight ) );
              Segment bottomIntersection = segment.Intersection( new Segment( rect.BottomRight, rect.BottomLeft ) );

              RectHelper.AdjustResultForIntersectionWithSide( ref result, ref distance, leftIntersection, point );
              RectHelper.AdjustResultForIntersectionWithSide( ref result, ref distance, topIntersection, point );
              RectHelper.AdjustResultForIntersectionWithSide( ref result, ref distance, rightIntersection, point );
              RectHelper.AdjustResultForIntersectionWithSide( ref result, ref distance, bottomIntersection, point );

              return result;
        }
Example #3
0
        public Segment Intersection( Segment segment )
        {
            // if either segment is empty, the intersection is also empty
              if( this.IsEmpty || segment.IsEmpty )
            return Segment.Empty;

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

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

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

              // okay, no easy answer, so let's do the math...
              Point p1 = this._p1;
              Vector v1 = this._p2 - this._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( this._p1, this._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 = this._p1;
            result._p2 = this._p2;
            result._isP1Excluded = this._isP1Excluded || !segment.Contains( this._p1 );
            result._isP2Excluded = this._isP2Excluded || !segment.Contains( this._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 || !this.Contains( segment._p1 );
            result._isP2Excluded = segment._isP2Excluded || !this.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 = this._p1;
            result._isP1Excluded = this._isP1Excluded || !segment.Contains( this._p1 );
              }
              else
              {
            result._p1 = this._p2;
            result._isP1Excluded = this._isP2Excluded || !segment.Contains( this._p2 );
              }
              if( includeSegmentP1 )
              {
            result._p2 = segment._p1;
            result._isP2Excluded = segment._isP1Excluded || !this.Contains( segment._p1 );
              }
              else
              {
            result._p2 = segment._p2;
            result._isP2Excluded = segment._isP2Excluded || !this.Contains( segment._p2 );
              }
              return result;
        }
Example #4
0
 public static bool AreVirtuallyEqual( Segment s1, Segment s2 )
 {
     // note: Segment struct already uses "virtually equal" approach
       return ( s1 == s2 );
 }
Example #5
0
 public bool Contains( Segment segment )
 {
     return ( segment == this.Intersection( segment ) );
 }