The title sucks.  More clearly, I have 2 points in 3D space.  I have an orientation vector.  If I put infinite planes normal to the vector thru the respective points, what is the distance between those 2 planes?

It’s probably still difficult to understand, so I drew an image:

Given a 3D space (x,y,z), the following geometry comprises the model:

In the sketch, you will find two points: (a,b,c) and (d,e,f).  There is a vector (“V”) that is defined by the coordinate from the origin (p,q,o).

I drew a plane on vector “V” that is perpendicular to the vector.  Basically, V is the plane’s normal.  I then placed a plane on each of the points that is parallel to the vector plane.

By measuring the distance between the parallel planes, this will return the projected distance between the points.

Why would anyone want to do this?  Here’s why I care to know.  I’m currently working on sorting 3D points in space via a certain direction (“V”).  Normally, I use the Z-axis to sort 3D points, which makes the math exceedingly simple.  However, once you deviate from the standard axis calculation (X-, Y-, or Z-axes), things get much more complicated.  The advantage to sorting points based on an arbitrary vector allows for amorphous geometries to be sorted.  If I continued to sort via the Z-axis, then my geometry would likely to conform to a semi-orthogonal aesthetic.  Currently, I’m developing new ways to automate Subdivision Surfaces which subscribe to Riemannian situations more than Euclidian.  An early example of this is my current in-progress project (Undersexualized Recursion Part 1) in the video below. But I’m digressing.

Back to the topic, here’s the math:

Just to review the ol’ Linear Algebra, here is the standard parametric expression of the equation of a line in 3D space:

x(t) = a + xt
y(t) = b + yt
z(t) = c + zt

where a is the x coordinate of a point on the line, b is the y, and c is the z.  The “x” corresponds to the x dimension of the vector “slope” of the line, and “y” to the y dim, and “z” to the z dim.

Using this configuration, the equation of a 3D plane is described as:

Ax + By + Cz + D = 0

where A is the x dimension of the vector (normal to the plane), B to the y, and C to the z.

The equation to solve for the distance between two parallel planes:

|D2 - D1|
d' =   _______________
√ (A² + B² + C²)

where D2 and D1 correspond to the “D” value in the equation of the plane mentioned above, and the “A,” “B,” and “C” and correspond to the respective coefficients in the same equation.

This is where Linear Alg book gets confusing.  Essentially, if you have the equation of the line that share the same normal vector of a plane, then some of those variables can be shared.

For the remainder of this article, I’m going to use the arbitrary “V” vector as (p,q,o).  That means the equations for the line and plane can be simplified to:

x(t) = a + pt
y(t) = b + qt
z(t) = c + ot
px + qy + oz + D = 0
|D2 - D1|
d' =   _______________
√ (p² + q² + o²)

We need to solve for the equation of the plane universally, so that we can isolate both plane’s D value.  For point (a,b,c):

p(x-a) + q(y-b) + o(z-c) = 0

px - pa + qy - qb + oz - oc = 0

px + qy + oz + (-pa - qb - oc) = 0

The same applies for the other point in space (d,e,f):

px + qy + oz + (-pd - qe - of) = 0

Let’s compare the original equations of the plane:

px + qy + oz + D1 = 0
px + qy + oz + (-pa - qb - oc) = 0
px + qy + oz + D2 = 0
px + qy + oz + (-pd - qe - of) = 0

Via substitution, we can assume that:

D1 = (-pa - qb - oc)
D2 = (-pd - qe - of)

Using these “D” values, we can resolve the Plane-distance equation:

abs((-pa - qb - oc) - (-pd - qe - of))
d' =   ____________________________________________
√ (p² + q² + o²)

Let’s test it out.  Let’s say there is a point A (a,b,c) = (1,3,4), point B (d,e,f) = (-2,0,5), and vector direction (p,q,o) = (0.5, 0.5, 0.75).

abs((-(0.5*2) - (0.5*0) - (.75*5)) - (-(0.5*1) - (0.5*3) - (.75*4)))
d' =   __________________________________________________________________________
√ (0.5² + 0.5² + 0.75²)

d’ = 2.1828 units

The image to the right displays this scenario in a 3D application.  The red planes are perpendicular to the normal vector “V” located at the origin.  The XYZ axes are displayed at the origin near the blue “V” vector.  The orange dimension shows the distance between the two planes.

That could be the end of this, but I wanted to express this in a C language in order to utilize this as a subroutine for some subdivision surface point cloud sorting.  If you are reading this article for the linear algebra, then you probably can just move on.  The remainder of this article will show the MEL language version of this formula.

I saved a copy of this subroutine on my wiki for easier access.

.

It requires only three arguments, the two points as a vector and the direction as a vector from the origin.  If you have a relative direction vector, you might need to subtract that or translate that to the origin to get an accurate measurement.  I’m sure you can augment the calculations too, if you wanted to have a relative vector.  Simple enough since all the vectors in this equation are the same (normals and origin vector).

global proc float getDistBetwPointsByVectorDirection(vector \$p1, vector \$p2, vector \$n) {
//0001D LLC (c) Nick Pisca 2015
//vector \$p1 = <<1,3,4>>; vector \$p2 = <<-2,0,5>>; vector \$n = <<0.5,0.5,0.75>>;
//d' = abs((-pd-qe-of)-(-pa-qb-oc))           where p1 = (a,b,c) and p2 = (d,e,f)
//    ---------------------------             and the vector direction = (p,q,o)
//         sqrt(p^2+q^2+o^2)
//Equation solved by Nick Pisca 2015.

float \$pd = (\$n.x) * (\$p2.x);
float \$qe = (\$n.y) * (\$p2.y);
float \$of = (\$n.z) * (\$p2.z);
float \$pa = (\$n.x) * (\$p1.x);
float \$qb = (\$n.y) * (\$p1.y);
float \$oc = (\$n.z) * (\$p1.z);

float \$f1 = ((-1*\$pd) - \$qe - \$of);
float \$f2 = ((-1*\$pa) - \$qb - \$oc);

float \$top = abs(\$f1 - \$f2);
float \$bot = sqrt( ((\$n.x)*(\$n.x)) + ((\$n.y)*(\$n.y)) + ((\$n.z)*(\$n.z)) );
float \$fin;
if (\$bot != 0.0 ) {
\$fin = \$top / \$bot;
} else {
\$fin = -1.0;
}

return \$fin;
}

I’m planning on porting this to C# for use in my plug-ins, but for now, it’s in MEL.  That’s simple enough to handle.