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;
          }
        }
      }
    }
    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 static bool AreVirtuallyEqual( Segment s1, Segment s2 )
 {
   // note: Segment struct already uses "virtually equal" approach
   return ( s1 == s2 );
 }
    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;
    }
 public bool Contains( Segment segment )
 {
   return ( segment == this.Intersection( segment ) );
 }
Example #6
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 #7
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);
        }