Just find the point where the lines are at their closest approach. If the point of closest approach is zero, they intersect.
Given two lines, defined by a point in R^3 and a vector that points in some direction. So we have a line defined as the locus of points
f(t) = a + va*t
and a second line defined as
g(s) = b + vb*s
Here ta and tb are parameters that allow you to define both lines parametrically. I'll createe some random vectors as an example.
a = rand(3,1)
b = rand(3,1)
va = rand(3,1)
vb = rand(3,1)
a =
0.20949
0.23808
0.37665
b =
0.83398
0.82809
0.80802
va =
0.43283
0.60998
0.36585
vb =
0.96745
0.79764
0.33452
What is the minimum distance between the lines? The easiest way to do this is using a linear regression. That is, solve for the parameters t and s, that minimizes the sum of squares of the residuals to the problem
va*t - vb*s = a - b
In MATLAB, we can solve that as:
ts = [va,-vb] \ (b - a)
ts =
0.66662
-0.3171
Can I convince you this does minimize the distance between the lines? Effectively you are solving for the pair of line parameters that results in the point of closest approach. t and s enter into the problem linearly, so we can use a linear regression to solve this, and that is what the backslash usage there does in MATLAB. So next, I'll show that fminsearch does compute the same result. That does not mean I want or recommend you should use fminsearch to do this! I am just showing you that what I wrote does work.
f = @(t) a + va*t;
g = @(s) b + vb*s;
D = @(ts) norm(f(ts(1)) - g(ts(2)));
D(ts)
ans =
0.11097
[tsmin,fval] = fminsearch(D,[1 1])
tsmin =
0.66665 -0.31708
fval =
0.11097
So the optimizer gives the same result. The point is, the simple solution is to use
to solve for the closest point of approach. If that point of closest approach has a distance of zero, to within some tolerance of your choice, then they intersect, at least as far as you are concerned.
If the distance between the lines is non-zero, then they NEVER intersect, since we have found the point of closest approach. Here, we can see the two points where the lines lie at their points of closest approach. As I said, they are not the same, or even close.
f(ts(1))
ans =
0.49803
0.6447
0.62053
g(ts(2))
ans =
0.5272
0.57517
0.70194
Having said all that, are there cases where this code will fail? Under what circumstances is there a problem? The most obvious is the case when the lines are parallel. Do two parallel lines ever intersect? Never so, UNLESS the lines are coincident.
I'll leave a and b as the same random vectors they were before, but now set va and vb equal. What happens?
vb = va;
ts = [va,-vb] \ (b - a)
Warning: Rank deficient, rank = 1, tol = 5.546402e-16.
ts =
1.1367
0
MATLAB gets upset. It gave a warning. telling us there is a problem.
f = @(t) a + va*t;
>> g = @(s) b + vb*s;
>> f(ts(1))
ans =
0.70148
0.93142
0.7925
>> g(ts(2))
ans =
0.83398
0.82809
0.80802
There are infinitely many pairs of points along those two lines that have the SAME distance. So even though we got a solution with a warning attached, the warning just told the lines were numerically parallel. MATLAB was unhappy because the solution is not unique. So understanding the problem we are solving allows us to understand the source of the warning message, to diagnose if this is an issue or not.