How to find closest point on line?

10,722

Solution 1

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;
}

Solution 2

// 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);
}

Solution 3

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.

Share:
10,722

Related videos on Youtube

Semimono
Author by

Semimono

Game Dev: I grew up making video games in Game Maker, grew into learning python and developing modifications for games such as Far Cry (example), Crysis, Unreal Tournament, and others. I went to school for computer programming and have continued to make video games as a hobby using Unity3D. For unity I've developed a voxel engine, an inverse kinematics dynamic animation system, and several game prototypes. Professional: After graduating from college, I started working in the professional world at various companies, developing software ranging from server monitoring suites to web applications to DevOps and build systems. I have experience in Java, C#, C++, C, Python, Perl, Bash, JavaScript, Lua, and GCL. I've worked with many frameworks, including GitHub, SVN, Maven, Gradle, TeamCity, Jenkins, CircleCI, Docker, Unity3D, Unreal Engine, CryEngine, Blaze, Borg, and Rapid. Outside of coding I have experience acting in theater and have gained some experience doing cinematography, videography, and video editing work. I have also become somewhat capable with Blender, Anim8or, Gimp, Inkscape, Audacity, and a handful of other tools I tend to use for making video game assets.

Updated on September 14, 2022

Comments

  • Semimono
    Semimono over 1 year

    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?

  • Semimono
    Semimono about 5 years
    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?
  • Ruzihm
    Ruzihm over 4 years
    @Semimono I added some details to this answer. Can't speak on performance.