Thursday October 17, 2019
 home | about | contact | Donations
 The Maths of 3D You can't have 3D without a little maths...

Misc 3D Principles - Maths

by bkenwright@xbdev.net

Closest Point On A Line

 CODE //////////////////////////////////////////////////////////////////////// //                                                                    // //                  Closest Point On A Line                           // //                                                                    // //////////////////////////////////////////////////////////////////////// float Distance(D3DXVECTOR3 vPoint1, D3DXVECTOR3 vPoint2 ) {       float Vt = vPoint1 - vPoint2;         float fLength = D3DXLenght( Vt );         return fLength; }     D3DXVECTOR3 ClosestPointOnLine( D3DXVECTOR3 vA, D3DXVECTOR3 vB,                                 D3DXVECTOR3 vPoint ) {       // vA-vB are the two points for our line.       // vPoint is our point.         vABDir = vB - vA;       D3DXVec3Normalize( &vABDir, &vABDir );         float d = Distance(vA, vB);         // Distance between A and vPoint       D3DXVECTOR3 v1 = vPoint - vA;         float t = Dot(vABDir, v1);         if( t<=0 )             return vA;         if( t>= d)             return vB;         D3DXVECTOR3 v3 = vABDir * t;         D3DXVECTOR3 vClosestPoint = vA + v3;         return vClosestPoint; }

I think a bit of an explanation is appropriate for this function. As at first it might not click...it just depends how good you are with your vectors and dot products etc...and not forgetting good old socahtoa :D

First we find our Line's direction...Hmmm...simple...yup...then we normalize it so it has an effective magnitude of '1'. Still with me?

Next we find another vector direction, but this time from one of our line ends to our point.

Now we have vABDir and v1....k

This is where socahtoa comes into play! Now remember what the Dot product is?...you've forgotten!..heheh
Well I'll show you it quickly here:

Dot(A, B) = |A|*|B| cos(angle)
= Ax*Bx + Ay*By + Az*Bz

Now if we plug in our values...and remember some simple trig

|vABDir| = 1, as we normalized it...keep remember this... its the secret to our whole success!

And remembering our laws of trig..I always use sohcahtoa (sine=opp/hyp, cos=adj/hyp, tan=opp/adj)

Of course we can re-arrange that equation...(I also use h-hyp, and a-adj)..to get:
a = h * cos(angle)

Now this is where we make our comparison!

Dot(vABDir,v1) = |vABDir|*|v1| cos(angle)     ( but |vABDir| = 1 )

So we have:

Dot(vABDir,v1) = |v1| cos(angle)

NOTE:  if we'd normalised both v1 and vABDir b, then our dot product would give us our standard answer, which is cos(angle)...which is what we usually use it for.

Soo??...uhhh?

a = h*cos(angle)...where a is the distance along our line 90 degrees to our point.  Remember you've got to think with vectors!  So by adding this distance to our original point, vA we can get the closest point along our line to the point!  But remember, if this length is longer than the distance from vA to vB, its closest point is vB.  And if its negative, its behine our vA point, so vA is our closest point.  We do these checks first.

 Visitor: 9534626  { 209.237.238.175 } Copyright (c) 2002-2017 xbdev.net - All rights reserved. Designated tutorial and software are the property of their respective owners.