Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know if a line intersects a plane in C#?

I have two points (a line segment) and a rectangle. I would like to know how to calculate if the line segment intersects the rectangle.

like image 290
Gelu Avatar asked Aug 27 '08 13:08

Gelu


People also ask

How does a line intersect a plane?

The intersection of a line and a plane is a point that satisfies both equations of the line and a plane. It is also possible for the line to lie along the plane and when that happens, the line is parallel to the plane.


1 Answers

From my "Geometry" class:

public struct Line {     public static Line Empty;      private PointF p1;     private PointF p2;      public Line(PointF p1, PointF p2)     {         this.p1 = p1;         this.p2 = p2;     }      public PointF P1     {         get { return p1; }         set { p1 = value; }     }      public PointF P2     {         get { return p2; }         set { p2 = value; }     }      public float X1     {         get { return p1.X; }         set { p1.X = value; }     }      public float X2     {         get { return p2.X; }         set { p2.X = value; }     }      public float Y1     {         get { return p1.Y; }         set { p1.Y = value; }     }      public float Y2     {         get { return p2.Y; }         set { p2.Y = value; }     } }  public struct Polygon: IEnumerable<PointF> {     private PointF[] points;      public Polygon(PointF[] points)     {         this.points = points;     }      public PointF[] Points     {         get { return points; }         set { points = value; }     }      public int Length     {         get { return points.Length; }     }      public PointF this[int index]     {         get { return points[index]; }         set { points[index] = value; }     }      public static implicit operator PointF[](Polygon polygon)     {         return polygon.points;     }      public static implicit operator Polygon(PointF[] points)     {         return new Polygon(points);     }      IEnumerator<PointF> IEnumerable<PointF>.GetEnumerator()     {         return (IEnumerator<PointF>)points.GetEnumerator();     }      public IEnumerator GetEnumerator()     {         return points.GetEnumerator();     } }  public enum Intersection {     None,     Tangent,     Intersection,     Containment }  public static class Geometry {      public static Intersection IntersectionOf(Line line, Polygon polygon)     {         if (polygon.Length == 0)         {             return Intersection.None;         }         if (polygon.Length == 1)         {             return IntersectionOf(polygon[0], line);         }         bool tangent = false;         for (int index = 0; index < polygon.Length; index++)         {             int index2 = (index + 1)%polygon.Length;             Intersection intersection = IntersectionOf(line, new Line(polygon[index], polygon[index2]));             if (intersection == Intersection.Intersection)             {                 return intersection;             }             if (intersection == Intersection.Tangent)             {                 tangent = true;             }         }         return tangent ? Intersection.Tangent : IntersectionOf(line.P1, polygon);     }      public static Intersection IntersectionOf(PointF point, Polygon polygon)     {         switch (polygon.Length)         {             case 0:                 return Intersection.None;             case 1:                 if (polygon[0].X == point.X && polygon[0].Y == point.Y)                 {                     return Intersection.Tangent;                 }                 else                 {                     return Intersection.None;                 }             case 2:                 return IntersectionOf(point, new Line(polygon[0], polygon[1]));         }          int counter = 0;         int i;         PointF p1;         int n = polygon.Length;         p1 = polygon[0];         if (point == p1)         {             return Intersection.Tangent;         }          for (i = 1; i <= n; i++)         {             PointF p2 = polygon[i % n];             if (point == p2)             {                 return Intersection.Tangent;             }             if (point.Y > Math.Min(p1.Y, p2.Y))             {                 if (point.Y <= Math.Max(p1.Y, p2.Y))                 {                     if (point.X <= Math.Max(p1.X, p2.X))                     {                         if (p1.Y != p2.Y)                         {                             double xinters = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;                             if (p1.X == p2.X || point.X <= xinters)                                 counter++;                         }                     }                 }             }             p1 = p2;         }          return (counter % 2 == 1) ? Intersection.Containment : Intersection.None;     }      public static Intersection IntersectionOf(PointF point, Line line)     {         float bottomY = Math.Min(line.Y1, line.Y2);         float topY = Math.Max(line.Y1, line.Y2);         bool heightIsRight = point.Y >= bottomY &&                              point.Y <= topY;         //Vertical line, slope is divideByZero error!         if (line.X1 == line.X2)         {             if (point.X == line.X1 && heightIsRight)             {                 return Intersection.Tangent;             }             else             {                 return Intersection.None;             }         }         float slope = (line.X2 - line.X1)/(line.Y2 - line.Y1);         bool onLine = (line.Y1 - point.Y) == (slope*(line.X1 - point.X));         if (onLine && heightIsRight)         {             return Intersection.Tangent;         }         else         {             return Intersection.None;         }     }  } 
like image 136
Chris Marasti-Georg Avatar answered Sep 22 '22 12:09

Chris Marasti-Georg