So if we think about what information we are given, a point and a line, we can easily make this all come together for us by drawing a line between the point and one endpoint of our line. For the ease of describing the situation, we'll assume that the point lies 'between' the two endpoints, but off to one side a little.
Now that we have a new line, we can use our knowledge of Projections to project a shadow onto our line. Once we know how long that side is (let's call it b) then we can square it.
The projection equation looks like this:
Proj (c onto a) = |c|*|a| /
|a|^2
Now, we know the length of the hypotenuse which is the length of our new line we can call 'c' (the magnitude) and we know the length of our a-side which is our shadow.
So we just plug them in and calculate the far side... the b-side. The code looks like this. There is some error detection here. Also the result is the squared-distance. Take the square root if you want the actual distance.
[adapted from Real-time Collision Detection - Ericson]
// this is highly optimal and very fast.
float GetSquareDistanceFromPointToLine (Vector v1, Vector v2, Vector pt)
{
Vector line = v2 - v1,
edge1 = pt - v1,
edge2 = pt - v2;
float MagnitudeOfProjection = edge1.Dot (line);
// the projection may put out point beyond the ends of the line.
if (MagnitudeOfProjection <= 0.0f)
return edge1.SquareMagnitude ();// distance to the point squared
float SquareMagnitudeOfLine = line.SquareMagnitude ();
// try the other edge, note how we use the already computed length
if (MagnitudeOfProjection >= SquareMagnitudeOfLine)
return edge2.SquareMagnitude();// distance to the point
// project perp vector onto the 'height' of the point
return edge1.SquareMagnitude() -
MagnitudeOfProjection * MagnitudeOfProjection /
SquareMagnitudeOfLine;
}
No comments:
Post a Comment