/// <summary> /// Returns all the perpendicular points on the ellipse from a given point 'from' /// </summary> public Point2d[] Perpendicular(Point2d from) { // Solved by Robert.P. in december 2012 // Note on solutions: // Quartic coefficients gotten from applying lagrange multiplier to minimize (x-i)^2+(y-j)^2 // with x^2/a^2+y^2/b^2-1=0 as constraint (a=1 because we work in standard position). // This gives a system of three equations F_x,F_y,F_lambda, which were solved with // resultant theory using 'eliminate' in maxima //work in standard position, retranslate solutions last Transform2d tostd = ToStandardPosition; from = from.GetTransformed(tostd); double b = sigratio, b2 = b * b, b4 = b2 * b2; double i = from.X, i2 = i * i; double j = from.Y, j2 = j * j; double x4 = b4 - 2 * b2 + 1; double x3 = 2 * b2 * i - 2 * i; double x2 = b2 * j2 + i2 - b4 + 2 * b2 - 1; double x1 = 2 * i - 2 * b2 * i; double x0 = -i2; double[] sols = RealPolynomial.SolveQuartic2(x4, x3, x2, x1, x0, 1e-16); if (sols == null) { return(null); } Point2dSet respts = new Point2dSet(); foreach (double x in sols) { double y = (1 - x * x) * b2; if (y < 0.0) { continue; } y = Math.Sqrt(y); for (int l = 0; l < 2; l++) { //both posetive and negative y:s can be solutions. Check with each possible //point that its perpendicular to ellipse (subtracting the inverse ellipse slope (=normal slope) with the slope from 'from' point) double err; err = y * (from.X - x) - x * b2 * (from.Y - y); if (Math.Abs(err) < 1e-6) { respts.Add(new Point2d(x, y)); } y = -y; //test negative solution as well } } respts.Transform(tostd.Inversed); return(respts.ToArray()); }