Point on a line nearest to another line

Started by
14 comments, last by CGameProgrammer 21 years, 5 months ago
I can't see why the method you gave would work. Of course, that doesn't necessarily mean it doesn't work.

What I can see working is the following:

Parameterize the two lines A and B as usual x = ta + A and x = tb + B (anything in bold is a vector) where a,b are normalized.

The closest points will be joined by a vector perpendicular to both lines, call this n = a x b .

Define a plane with normal perpendicular to both n and b and passing through the point B . The closest point on line A to line B will then be the intersection between this plane and the line A. Lets call this point r .

r is in the plane defined above so

(r - B ) . (n x b ) = 0

and r is also on the line A so

r = t a + A

for some t.

Substituting the second equation in the first gives

t = ( (B - A ) . (n x b ) ) / (a . (n x b ) )

and then substitute this back to find r . It's then pretty simple to find the corresponding point on line B.

This is probably the same to the method you just put up. But hope it helps anyway.

[edited by - sQuid on November 3, 2002 10:43:42 PM]
Advertisement
My projection idea would probably work, but you would need to know the projection math
The projection method finds the shortest distant constrained to be in the plane that is projected into... i.e. it''s not guaranteed to be *the* shortest path, just a path that might be short

"3D Game Engine Design" by David Eberly
The minimum distance occurs when grad(Q) = (0,0)
Q(s, t) = | L0(s) - L1(t) |
where L0 & L1 are the parameteric equations for the lines

struct Line{float M[3];float B[3];};float DistanceSquare(Line line1, Line line2, float& s, float& t){diff = line0.B - line1.B;a =  dot( line0.M, line0.M );b = -dot( line0.M, line1.N );d =  dot( line1.M, line1.M );d =  dot( line0.M, diff );f =  dot( diff, diff );det = |a*b - b*b|;//note this is a fuzzy-floating float compare (use an epsilon etc...)if(det > 0)   {   e = -dot( line1.M, diff );   invdet = 1/det;   //Q(s,t) is the closest pair of points   s = (b*e - c*d) * invdet;   t = (b*d - a*e) * invdet;   //this is the distance squared   return s*(a*s + b*t 2*d) + t*( b*s + c*t + 2*e) + f;   }else   {//lines are parallel   s = -d/a;   t = 0;   return d*s + f;   }} 

- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
The results from the method I posted are either correct or just close, I can''t tell. There''s something strange going on with some part of the collision so I''ll try your method, sQuid.

But is it really necessary to say (a x b) x b? That''s what n x b is. Is there a simpler way to put that?

~CGameProgrammer( );
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
But I already know the distance between the two lines, Magmai. I wrote it in the main post in this thread. And it works in all cases

At least, it appears to.

~CGameProgrammer( );
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.
Well sQuid, your method produces identical results as the method I posted. And because both methods involve two cross-products and two dot-products (if you use a variable for n x b and a x b) there appears to be no advantage to using either over the other.

~CGameProgrammer( );
~CGameProgrammer( );Developer Image Exchange -- New Features: Upload screenshots of your games (size is unlimited) and upload the game itself (up to 10MB). Free. No registration needed.

This topic is closed to new replies.

Advertisement