I have a point (A) and a vector (V) (suppose it's infinite length), and I want to find the closest point (B) on the line to my original point (A). What's the simplest expression using Unity Vector2's or Vector3's to get this?
5 Answers
Infinite length:
If you have line with infinite length with start and direction, calculate the dot product of the line direction then multiply it by the direction and add the starting point to it.
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 direction, Vector2 point)
{
direction.Normalize();
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, direction);
return origin + direction * dotP;
}
Finite length:
If you have line with finite length with start to end positions, get the heading the perform a projection from the starting point to the. Also, use Mathf.Clamp
to clap it just in case the line is off.
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 end, Vector2 point)
{
//Get heading
Vector2 heading = (end - origin);
float magnitudeMax = heading.magnitude;
heading.Normalize();
//Do projection from the point but clamp it
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, heading);
dotP = Mathf.Clamp(dotP, 0f, magnitudeMax);
return origin + heading * dotP;
}

- 121,791
- 22
- 236
- 328
// For finite lines:
Vector3 GetClosestPointOnFiniteLine(Vector3 point, Vector3 line_start, Vector3 line_end)
{
Vector3 line_direction = line_end - line_start;
float line_length = line_direction.magnitude;
line_direction.Normalize();
float project_length = Mathf.Clamp(Vector3.Dot(point - line_start, line_direction), 0f, line_length);
return line_start + line_direction * project_length;
}
// For infinite lines:
Vector3 GetClosestPointOnInfiniteLine(Vector3 point, Vector3 line_start, Vector3 line_end)
{
return line_start + Vector3.Project(point - line_start, line_end - line_start);
}

- 4,173
- 1
- 9
- 19
For infinite lines:
Vector3 GetPoint(Vector3 p, Vector3 a, Vector3 b)
{
return a + Vector3.Project(p - a, b - a);
}
This method will work with Vector3
inputs, and will also work if the arguments are Vector2
and are automatically converted to Vector2
. The output will implicitly convert to a Vector2
if needed.
-
I like how succinct this solution is, but I wouldn't mind a bit more explanation. Is this for infinite or finite lines? Looking up the docs there isn't a Project method for Vector2, might be nice to mention this is only for Vector3 (unless you bother to make Vector3 values with z=0). Any comments on performance? Is this better or worse on performance than any of the other answers? Does this answer have any benefits or drawbacks compared to other answers besides the obvious terseness? – Semimono Mar 15 '19 at 18:37
-
1@Semimono I added some details to this answer. Can't speak on performance. – Ruzihm Dec 23 '19 at 20:42
For infinite lines
private Vector3 GetPointOnLine(Vector3 lineOrigin, Vector3 lineDirection, Vector3 point)
=> lineOrigin - point - Vector3.Dot(lineOrigin - point, lineDirection) * lineDirection;
Put in the origin and direction of your line as well as the point you want to find the closest point to and voilá...

- 346
- 2
- 15
public Vector2 FindNearestPointOnLine(Vector2 origin, Vector2 end, Vector2 point)
{
//Get heading
Vector2 heading = (end - origin);
float magnitudeMax = heading.magnitude();
heading = Vector2.Normalize(heading);
//Do projection from the point but clamp it
Vector2 lhs = point - origin;
float dotP = Vector2.Dot(lhs, heading);
dotP = UnityEngine.Mathf.Clamp(dotP, 0f, magnitudeMax);
return origin + heading * dotP;
}
vector2.magnitude not found

- 2,644
- 1
- 21
- 27
-
As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 22 '22 at 03:45