Line-Segment Ellipse Intersection

A line segment between points $$A$$ and $$B$$ can be defined as

$L(t) = A + (B-A)t = \left[\begin{array}{c}x(t)\\y(t)\end{array}\right]\forall t\in[0,1]$

On the other hand, an axis aligned ellipse with its radii $$r_x$$ and $$r_y$$ can be seen as

$\frac{x^2}{r_x^2} + \frac{y^2}{r_y^2}=1$

When substituting the $$x$$ and $$y$$ coordinates of the line into the equation of the ellipse, we get

$\begin{array}{rrl} & \frac{x^2(t)}{r_x^2} + \frac{y^2(t)}{r_y^2}&=1\\ \Leftrightarrow & \frac{(A_x + (B_x-A_x)t)^2}{r_x^2} + \frac{(A_y + (B_y-A_y)t)^2}{r_y^2}&=1\\ \Leftrightarrow & r_x^2(A_y + (B_y-A_y)t)^2+ r_y^2(A_x + (B_x-A_x)t)^2 &=r_x^2r_y^2\\ \Leftrightarrow & \underbrace{(r_x^2(B_y-A_y)^2+r_y^2(B_x-A_x)^2)}_{=a}t^2 + \underbrace{(2r_x^2A_y(B_y-A_y)+2r_y^2A_x(B_x-A_x))}_{=b}t + \underbrace{r_x^2A_y^2 + r_y^2A_x^2 -r_x^2r_y^2}_{=c} &=0\\ \end{array}$

Now this is a quadratic equation in $$t$$, which we can solve using

$t = \frac{-b\pm\sqrt{b^2-4ac}}{2a}$

If the discriminant $$D=b^2-4ac$$ in the square root becomes negative, we can conclude, there is no solution. For $$D=0$$, it is clear that only one solution is possible and for $$D>0$$, we get two solutions. Now The resulting points are

$P = A+(B-A)t$

For the general case, that an ellipse is positioned at point $$C$$ and is rotated by $$\theta$$, we can transform the line segment into the ellipses space, by assuming the anchor points $$A$$ and $$B$$ we used previously were originally transformed with

$A = \text{Rot}(-\theta) (A'-C)\\B = \text{Rot}(-\theta) (B'-C)$

And after all calculations, we transform the resulting points $$P$$ back to the original space:

$P' = \text{Rot}(\theta)P + C$

JavaScript Implementation

function EllipseLine(A, B, C, rx, ry, phi) {

A = Vector2(A).sub(C).rotate(-phi);
B = Vector2(B).sub(C).rotate(-phi);

rx *= rx;
ry *= ry;

const ret = [];

const v = Vector2.fromPoints(A, B);

const a = rx * v.y * v.y + ry * v.x * v.x;
const b = 2 * (rx * A.y * v.y + ry * A.x * v.x);
const c = rx * A.y * A.y + ry * A.x * A.x - rx * ry;

const D = b * b - 4 * a * c; // Discriminant

if (D >= 0) {

const sqrtD = Math.sqrt(D);
const t1 = (-b + sqrtD) / (2 * a);
const t2 = (-b - sqrtD) / (2 * a);

if (0 <= t1 && t1 <= 1)
}