public static Vector2[] EllipseLineIntersections(
double H, double K, double A, double B,
double X1, double Y1, double X2, double Y2)
{
// This is pretty inefficient tbh, look for a better method.
// If it's vertical, we can't calculate it's slope.
if (X1 == X2)
{
if (System.Math.Abs(X1 - H) > A)
return new Vector2[] { };
double V = B * System.Math.Sqrt(1 - System.Math.Pow((X1 - H) / A, 2.0));
double iy1 = K + V;
double iy2 = K - V;
float fX1 = (float)X1;
return new Vector2[] {
new Vector2(fX1, (float)(iy1)),
new Vector2(fX1, (float)(iy2))
};
}
else
{
var intersections = new List<Vector2>();
double m, c, a_sqrd, b_sqrd, U, V, W, discr;
a_sqrd = A * A;
b_sqrd = B * B;
m = (Y2 - Y1) / (X2 - X1);
c = Y2 - m * X2;
U = a_sqrd * m * m + b_sqrd;
V = 2 * (a_sqrd * m * (c - K) - b_sqrd);
W = a_sqrd * System.Math.Pow(c - K, 2.0) - a_sqrd * b_sqrd + b_sqrd * H * H;
discr = V * V - 4 * U * W;
if (discr < 0)
return intersections.ToArray();
else if (discr == 0)
{
double ix = -V / (2 * U);
double iy = m * ix + c;
intersections.Add(new Vector2((float)ix, (float)iy));
}
else
{
double U2 = 2 * U;
double sqrt_discr = System.Math.Sqrt(discr);
double ix1 = (sqrt_discr - V) / U2;
double ix2 = (-sqrt_discr - V) / U2;
intersections.Add(new Vector2((float)ix1, (float)(m * ix1 + c)));
intersections.Add(new Vector2((float)ix2, (float)(m * ix2 + c)));
}
return intersections.ToArray();
}
}