public int Intersect(LineSegment seg, Point2D pt0, Point2D pt1) { if (pt0 == null) pt0 = new Point2D(); if (pt1 == null) pt1 = new Point2D(); // Solution is found by parameterizing the line segment and // substituting those values into the ellipse equation. // Results in a quadratic equation. double x1 = _center.X; double y1 = _center.Y; double u1 = seg.A.X; double v1 = seg.A.Y; double u2 = seg.B.X; double v2 = seg.B.Y; double dx = u2 - u1; double dy = v2 - v1; double q0 = _k1 * Sqr(u1 - x1) + _k2 * (u1 - x1) * (v1 - y1) + _k3 * Sqr(v1 - y1) - 1; double q1 = (2 * _k1 * dx * (u1 - x1)) + (_k2 * dx * (v1 - y1)) + (_k2 * dy * (u1 - x1)) + (2 * _k3 * dy * (v1 - y1)); double q2 = (_k1 * Sqr(dx)) + (_k2 * dx * dy) + (_k3 * Sqr(dy)); // Compare q1^2 to 4*q0*q2 to see how quadratic solves double d = Sqr(q1) - (4 * q0 * q2); if (d < 0) { // Roots are complex valued. Line containing the segment does // not intersect the ellipse return 0; } if (d == 0) { // One real-valued root - line is tangent to the ellipse double t = -q1 / (2 * q2); if (0 <= t && t <= 1) { // Intersection occurs along line segment pt0.X = u1 + t * dx; pt0.Y = v1 + t * dy; return 1; } return 0; } else { // Two distinct real-valued roots. Solve for the roots and see if // they fall along the line segment int n = 0; double q = Math.Sqrt(d); double t = (-q1 - q) / (2 * q2); if (0 <= t && t <= 1) { // Intersection occurs along line segment pt0.X = u1 + t * dx; pt0.Y = v1 + t * dy; n++; } // 2nd root t = (-q1 + q) / (2 * q2); if (0 <= t && t <= 1) { if (n == 0) { pt0.X = u1 + t * dx; pt0.Y = v1 + t * dy; n++; } else { pt1.X = u1 + t * dx; pt1.Y = v1 + t * dy; n++; } } return n; } }
public int Intersect(LineSegment seg, Point2D pt0, Point2D pt1) { if (pt0 == null) { pt0 = new Point2D(); } if (pt1 == null) { pt1 = new Point2D(); } // Solution is found by parameterizing the line segment and // substituting those values into the ellipse equation. // Results in a quadratic equation. double x1 = _center.X; double y1 = _center.Y; double u1 = seg.A.X; double v1 = seg.A.Y; double u2 = seg.B.X; double v2 = seg.B.Y; double dx = u2 - u1; double dy = v2 - v1; double q0 = _k1 * Sqr(u1 - x1) + _k2 * (u1 - x1) * (v1 - y1) + _k3 * Sqr(v1 - y1) - 1; double q1 = (2 * _k1 * dx * (u1 - x1)) + (_k2 * dx * (v1 - y1)) + (_k2 * dy * (u1 - x1)) + (2 * _k3 * dy * (v1 - y1)); double q2 = (_k1 * Sqr(dx)) + (_k2 * dx * dy) + (_k3 * Sqr(dy)); // Compare q1^2 to 4*q0*q2 to see how quadratic solves double d = Sqr(q1) - (4 * q0 * q2); if (d < 0) { // Roots are complex valued. Line containing the segment does // not intersect the ellipse return(0); } if (d == 0) { // One real-valued root - line is tangent to the ellipse double t = -q1 / (2 * q2); if (0 <= t && t <= 1) { // Intersection occurs along line segment pt0.X = u1 + t * dx; pt0.Y = v1 + t * dy; return(1); } return(0); } else { // Two distinct real-valued roots. Solve for the roots and see if // they fall along the line segment int n = 0; double q = Math.Sqrt(d); double t = (-q1 - q) / (2 * q2); if (0 <= t && t <= 1) { // Intersection occurs along line segment pt0.X = u1 + t * dx; pt0.Y = v1 + t * dy; n++; } // 2nd root t = (-q1 + q) / (2 * q2); if (0 <= t && t <= 1) { if (n == 0) { pt0.X = u1 + t * dx; pt0.Y = v1 + t * dy; n++; } else { pt1.X = u1 + t * dx; pt1.Y = v1 + t * dy; n++; } } return(n); } }
public IntersectCase Intersect(Rectangle rectangle) { // Test if all 4 corners of the rectangle are inside the ellipse var ul = new Point2D(rectangle.MinPt.X, rectangle.MaxPt.Y); var ur = new Point2D(rectangle.MaxPt.X, rectangle.MaxPt.Y); var ll = new Point2D(rectangle.MinPt.X, rectangle.MinPt.Y); var lr = new Point2D(rectangle.MaxPt.X, rectangle.MinPt.Y); if (Contains(ul) && Contains(ur) && Contains(ll) && Contains(lr)) return IntersectCase.CONTAINS; // Test if any of the rectangle edges intersect Point2D pt0 = new Point2D(), pt1 = new Point2D(); var bottom = new LineSegment(ll, lr); if (Intersect(bottom, pt0, pt1) > 0) return IntersectCase.INTERSECTS; var top = new LineSegment(ul, ur); if (Intersect(top, pt0, pt1) > 0) return IntersectCase.INTERSECTS; var left = new LineSegment(ll, ul); if (Intersect(left, pt0, pt1) > 0) return IntersectCase.INTERSECTS; var right = new LineSegment(lr, ur); if (Intersect(right, pt0, pt1) > 0) return IntersectCase.INTERSECTS; // Ellipse does not intersect any edge : since the case for the ellipse // containing the rectangle was considered above then if the center // is inside the ellipse is fully inside and if center is outside // the ellipse is fully outside return (rectangle.Contains(_center)) ? IntersectCase.WITHIN : IntersectCase.OUTSIDE; }