distance from given point to given ellipse

Consider a bounding circle around the given point (c, d), which passes through the nearest point on the ellipse. From the diagram it is clear that the closest point is such that a line drawn from it to the given point must be perpendicular to the shared tangent of the ellipse and circle. Any other points would be outside the circle and so must be further away from the given point.

enter image description here

So the point you are looking for is not the intersection between the line and the ellipse, but the point (x, y) in the diagram.

Gradient of tangent:

enter image description here

Gradient of line:

enter image description here

Condition for perpedicular lines - product of gradients = -1:

enter image description here

enter image description here

enter image description here

When rearranged and substituted into the equation of your ellipse...

enter image description here

...this will give two nasty quartic (4th-degree polynomial) equations in terms of either x or y. AFAIK there are no general analytical (exact algebraic) methods to solve them. You could try an iterative method - look up the Newton-Raphson iterative root-finding algorithm.

Take a look at this very good paper on the subject: http://www.spaceroots.org/documents/distance/distance-to-ellipse.pdf

Sorry for the incomplete answer - I totally blame the laws of mathematics and nature...

EDIT: oops, i seem to have a and b the wrong way round in the diagram xD


There is a relatively simple numerical method with better convergence than Newtons Method. I have a blog post about why it works http://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/

This implementation works without any trig functions:

def solve(semi_major, semi_minor, p):  
    px = abs(p[0])
    py = abs(p[1])

    tx = 0.707
    ty = 0.707

    a = semi_major
    b = semi_minor

    for x in range(0, 3):
        x = a * tx
        y = b * ty

        ex = (a*a - b*b) * tx**3 / a
        ey = (b*b - a*a) * ty**3 / b

        rx = x - ex
        ry = y - ey

        qx = px - ex
        qy = py - ey

        r = math.hypot(ry, rx)
        q = math.hypot(qy, qx)

        tx = min(1, max(0, (qx * r / q + ex) / a))
        ty = min(1, max(0, (qy * r / q + ey) / b))
        t = math.hypot(ty, tx)
        tx /= t 
        ty /= t 

    return (math.copysign(a * tx, p[0]), math.copysign(b * ty, p[1]))

Convergence

Credit to Adrian Stephens for the Trig-Free Optimization.