Re: [Algorithms] 3d Lines Intersection
Brought to you by:
vexxed72
|
From: <ro...@do...> - 2000-07-29 15:57:42
|
Albert_J wrote:
>Hi,
>
>Is there a good algo for finding a point of intersection between two *3D lines*?
>The lines is specified by their point (x,y,z) and their direction (dx,dy,dz)
>
>I've searched the web, but all of them seems to explain about 2D lines intersection only.
The problem is that in 3D almost all pairs of lines do not intersect
(as opposed to 2D where every pair of non parallel lines intersects).
Even if the logic of the construction of the two lines is such that
you know they must intersect, any computational intersection test will
be subject to rounding errors which, in all probability, will yield a
negative result.
The best you can do computationally is to find the two points, one on
each line, which are nearest. You may or may not want to call the
lines "intersecting" depending on the distance between these two
points and your error tolerance.
So if your two lines are specified by vectors X1, DX1, X2, DX2,
namely
X1= (x1, y1, z1),
DX1 = (dx1, dy1, dz1)
X2 = (x2, y2, z2),
DX2 = (dx2, dy2, dz2)
write down the vector parametric representations of the general point
one each of the two lines
X1 + s DX1
X2 + t DX2.
where s and t are INDEPENDENT real parameters.
You want to find the values of s and t that make the distance between
these two points as small as possible. Write down the expression for
the distance between the two points, or rather the square of the
distance ( more convenient to avoid square roots), in terms of these
two parameters. Using elementary vector geometry this squared
distance is
distance squared =
| (X1 + sDX1) - (X2 + tDX2) |^2
= |(X1 - X2) + s DX1 - t DX2)|^2
= ((X1 - X2) + s DX1 - t DX2) . ( (X1 - X2) + s DX1 - t DX2))
where . means dot product.
Apply the elementary algebraic properties of dot product and collect
terms that are like in s and t and you get
s^2 DX1.DX1 + t^2 DX2.DX2 - 2st DX1.DX2 +
s DX1. (X1 - X2) - t DX2. (X1 - X2) + (X1 - X2).(X1 - X2)
This distance-squared function is of the form
as^2 + bt^2 + c st + ds + et + f
where a, b, c, d, e, f are known scalars computed from your line data
and s and t are independent variables.
This is a general quadratic function of two independent variables s
and t. We seek to find the values of s and t that make it as small as
possible. The best tool for this minization problem is the elementary
differential calculus of two variables, which tells us that the
minimum value occurs where the first partial derivatives with respect
to each of the variables is zero. So differentiating first with
respect to s and then with respect to t gives two equations
2as + ct + d = 0
2bt + cs + e = 0
This is a system of two linear equations in two unknowns s and t,
which you know how to solve from high school algebra. It will have a
unique solution if the lines are not parallel.
Plug the resulting values of s and t back into the distance-squared
formula and see if that is close enough to zero so that you want to
call it an intersection. In any case, if you plug the values of s and
t back into the parametric expressions for the two lines you get the
two closest points, one on each line.
P.S. You can avoid calculus and still find the two nearest points by
using the fact from Euclidean solid geometry that the closest two
points are the two feet of the mutual perpendicular between the two
lines, the mutual perpendicular being unique if the lines are not
parallel. Write down the expression for the vector joining a general
point of each line, as a function of s and t, and write down the
equations that say that the dot product of this vector with each of
DX1 and DX2 is zero (this is the mutual perpendicularity condition).
i.e. DX1. ((X1 - X2) + s DX1 + t DX2) = 0
DX2. ((X1 - X2) + s DX1 + t DX2)) = 0
The resulting two equations is a 2x2 linear system equivalent to the
one above. The reason I chose the calculus approach is because I
didn't just want to find the two closest points, but also to test for
(near) intersection, which means I would have had to know the distance
function anyway, so I chose to start with the distance function, and
followed my nose from there.
|