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.
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.
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; } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With