[Math] How to find distance between a point and 3D surface, solution to general quadric equation, and visualizing such a surface

differential-geometryquadrics

Goal:

I am writing software to visualize 3-D objects in Python, using libraries such as sympy, numpy, and matplotlib.pyplot. I would like to fit the best surface to a small number of points. This is why I want to find the smallest distance between a point and a quadric surface

==============================================================================
$$Ax^2 + By^2 + Cz^2 + Dxy + Exz + Fyz + Gx + Hy + Iz + J = 0$$

==============================================================================

Questions:

1) How can I find a solution to this equation, given particular coefficients $A, B, …, J$ ? This is for the purpose of solving question 2, which is the key question:

2) How can I find the smallest Euclidean distance between that surface and a point? I have access to a computer; I'm using python2 and sympy at the moment.

3) Is there software I can use to visualize such a surface?

4) Are these surfaces known as "manifolds" in proper mathematical terms? From brief reading, it sounds like a manifold is a more general mathematical object than the object the word "surface" I'm using denotes

I've looked here, here, here, here, and here.

Best Answer

This solved the problem I cared about. Hope it's also useful to others. For convenience, once again the relevant equation is:

========================================================================= $$ Ax^2 + By^2 + Cz^2 + Dxy + Exz + Fyz + Gx + Hy + Iz + J = 0 $$

=========================================================================

python2 code:

from __future__ import division
from sympy import *

if __name__=='__main__':
    x = Symbol('x'); y = Symbol('y'); z = Symbol('z'); lambd = Symbol('lambd') 
    # lambda is a keyword; I didn't want to rename
    A = 0
    B = 0
    C = 0
    D = 0
    E = 0
    F = 0
    G = 1
    H = 1
    I = 1
    J = 0
    #x_e means x_external
    x_e = 1; y_e = 1; z_e = 1.1
    var_list            = [x,y,z,lambd]
    eq_list             = []
    eq_list.append(2*x - 2*x_e + 2*lambd*A*x + lambd*D*y + lambd*E*z + lambd*G)
    eq_list.append(2*y - 2*y_e + 2*lambd*B*y + lambd*D*x + lambd*F*z + lambd*H)
    eq_list.append(2*z - 2*z_e + 2*lambd*C*z + lambd*E*x + lambd*F*y + lambd*I)
    eq_list.append(   A*(x**2)  + B*(y**2)  + C*(y**2)
                    + D*x*y     + E*x*z     + F*y*z
                    + G*x       + H*y       + I*z
                    + J)
    print solve(eq_list, var_list, dict=True)

===================================================================

How to reuse my code for your problem:

x_e, y_e, and z_e should be the values of the relevant "external" point you care about. Similar for the values of A, B, ..., J. But this system of equations should work for solving the min dist between a general quadric and a point.

reference: Finding shortest distance between a point and a surface

===================================================================

Visualization:

I used GNU Octave to visualize. It's the free version of MATLAB, which you can use if you've paid for it. See the code from this post:

gv = linspace(-30,30,50); % adjust for appropriate domain
[xx yy zz]=meshgrid(gv, gv, gv);
F = A*xx.*xx + B*yy.*yy + C*zz.*zz+ ... etc

figure
isosurface(xx, yy, zz, F, 0)

For me, visualization is surprisingly unhelpful for checking how well my code is working. I really needed an extra "distance between point and surface" calculator to debug properly, which is not something easy to visualize, even with GNU Octave. Still, very cool to see the quadric graphed. Hope it helps someone else more

Related Question