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;
          }
        }
      }
    }
예제 #2
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;
                    }
                }
            }
        }
예제 #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);
        }
    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;
    }