I have equation of a surface (for example: x^2+y^2=400) and a point (for example: 1,2,3). I want to calculate the approx min. distance between that surface and a point.
I tried using following function for it:
def distance_to_surface(equation, point):
# Define a function that returns the gradient of the surface equation
x, y, z = symbols('x y z')
expr = eval(equation)
dx = diff(expr, x)
dy = diff(expr, y)
dz = diff(expr, z)
grad_expr = np.array([dx, dy, dz])
grad_func = lambdify((x, y, z), grad_expr, modules=['numpy' , "sympy"])
# Find a point on the surface by solving the equation for one of the variables
# Here, we solve for z to find a point on the surface with the same x and y coordinates as the given point
x0, y0, z0 = point
z_func = lambdify((x, y), z - expr, 'numpy')
z_surface = z_func(x0, y0)
surface_point = np.array([x0, y0, z_surface])
# Calculate the vector between the given point and the surface point
v = point - surface_point
# Calculate the normal vector to the surface at the surface point
epsilon = 1e-6
normal = np.array([
grad_func(x0 + epsilon, y0) - grad_func(x0 - epsilon, y0),
grad_func(x0, y0 + epsilon) - grad_func(x0, y0 - epsilon),
-1
])
normal = normal / np.linalg.norm(normal)
# Calculate the distance between the given point and the surface
distance = np.abs(np.dot(v, normal))
return distance
Your example can be solved purely symbolically by SymPy with a Lagrange multiplier. We want to find the distance from the point
(1, 2, 3)to the closest point on the cylinderx**2 + y**2 = 400.The solution:
This gives the solutions for
d^2as405 +- 40*sqrt(5). One of those is the squared distance to the nearest point and the other to the furthest point (furthest within the planez=3).This example is easy to solve symbolically because it is all polynomials. For more complicated surface equations you might want to use a numeric solver in which case just use the SciPy one rather than writing your own:
The function value
~315is approximately equal to the exact value computed before:Again that's the square of the distance so the actual distance is
That number makes sense because you have a point near the centre of a cylinder of radius 20.