The points on the infinite right circular cylinder are at distance $r$ from the axis of the cylinder. The distance between point $\vec{p}$ and line through $\vec{p}_1$ and $\vec{p}_2$ is
$$d = \frac{\left \lvert (\vec{p} - \vec{p}_1) \times (\vec{p} - \vec{p}_2) \right \rvert}{\left \lvert \vec{p}_1 - \vec{p}_2 \right \rvert}$$
so we can square that to get our equation describing an infinite right circular cylinder of radius $r$ whose axis passes through points $\vec{p}_1$ and $\vec{p}_2$:
$$r^2 = \frac{\left \lvert (\vec{p} - \vec{p}_1) \times (\vec{p} - \vec{p}_2) \right \rvert^2}{\left \lvert \vec{p}_1 - \vec{p}_2 \right \rvert^2}$$
That can be written using Cartesian coordinates as
$$r^2 = \frac{ \left ( (y-y_1)(z-z_2) - (z-z_1)(y-y_2) \right )^2 }{(x_2-x_1)^2 + (y_2-y_1)^2 + (z_2-z_1)^2 } + \frac{ \left ( (z-z_1)(x-x_2) - (x-x_1)(z-z_2) \right )^2 }{(x_2-x_1)^2 + (y_2-y_1)^2 + (z_2-z_1)^2 } + \frac{ \left ( (x-x_1)(y-y_2) - (y-y_1)(x-x_2) \right )^2 }{(x_2-x_1)^2 + (y_2-y_1)^2 + (z_2-z_1)^2 }$$
which we can convert to standard form by multiplying by the right-hand-side denominator, and moving all to the same side:
$$\left ( (y-y_1)(z-z_2) - (z-z_1)(y-y_2) \right )^2 + \left ( (z-z_1)(x-x_2) - (x-x_1)(z-z_2) \right )^2 + \left ( (x-x_1)(y-y_2) - (y-y_1)(x-x_2) \right )^2 - r^2 \left ( (x_2-x_1)^2 + (y_2-y_1)^2 + (z_2-z_1)^2 \right ) = 0$$
I have at my Wikipedia talk page the equations to locate the intersection between a line passing through origin and an arbitrary right circular cylinder; without caps, with flat end caps, or with spherical end caps. The key point is that when the ray (or line we are testing intersection for) passes through origin (so we use an unit vector $\hat{n}$, $\lvert\hat{n}\rvert=1$, to describe the line or ray), the equations become rather straightforward.
If the underlying problem is related to grinding spheres using a grinding wheel -- a cutting plane, essentially -- then a simplified coordinate system where origin is the sphere origin, and $\hat{z}$ is along the rotation axis, makes for easy calculations. Consider this illustration:
The contact point scribes a circle around the axis of rotation. We can describe this circle using a single scalar, $d$, which is the signed distance from the origin to the plane of that circle, along the axis of rotation. If the circle is not on the surface of the sphere, but perhaps inside it, then we need a second scalar, $r$, to describe the radius of the circle (around the axis of the rotation).
If the radius of the sphere is $R$, then on the surface of the sphere $r = \sqrt{R^2-d^2}$, of course.
If we include the cutting or abrasion done by the wheel, then two pairs of scalars are needed: $(d_1,r_1)$ and $(d_2,r_2)$. If we assume the grinding wheel is planar, and stays at a fixed location with a perfect cut for at least one rotation of the sphere, the removed section of the sphere leaves a flat facet. Mathematically, $$r(d) = r_1 + \left ( d - d_1 \right ) \frac{r_2 - r_1}{d_2 - d_1}$$
where $d_1 \le d \le d_2$. Remember, $d$ is the distance along the axis of rotation, and $r$ the circle radius (around a point on the axis of rotation, at distance $d$ from the center of the sphere); that is why the dependence above is linear too.
If the axis of the grinding wheel always intersects the rotation axis, and you call up $z$ and right $x$ in the above diagram, then $(d,r) = (z,x)$, and the primary problem (surface of revolution caused by grinding, or shape of the "sphere" after several grinds) reduces to planar (2D) vector calculus.
If we also have the axis of rotation $\hat{n}$ in some fixed sphere coordinate system, it is easy to calculate the "ribbons" each grind cuts into the sphere, either parametrically (using say $0 \le u \le \pi$ along the circular ribbon, and $0 \le v \le 1$ across the ribbon -- useful for visualization) or algebraically.
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
Best Answer
If the axis of the cylinder is the line through $\vec{x}_0 = (x_0,y_0,z_0)$ and in the direction of $\vec{v} = (a,b,c)$ with radius $R$, assuming $|\vec{v}| = 1$, we can write the equation of the cylinder as the set of all points $\vec{x} = (x,y,z)$ satisfying:
$$|\vec{x} - \vec{x}_0|^{2} = R^{2} + [(\vec{x} - \vec{x}_0)\bullet \vec{v}]^{2}$$