# 3DNearest Point on a 3d line to a point (Get the point?)

#### RujiK

##### Member
It's me, the 100% 3D Math genius who needs some help.

I have a point (xx,yy,zz) and an infinite vector/3d line defined by two points (x0,y0,z0) and (x1,y1,z1). How do I find the NEAREST POINT ON THE LINE to my other point?

THAT'S IT! But here is some fluff to show you that I did try wicked hard:

FLUFF: (Feel free to ignore the rest if you are 3d smart)

Currently, I can find the DISTANCE between the line and the point, but I need the position and I'm not sure if the distance actually helps.

GML:
``````    //Find distance from point to vector. THIS WORKS!
V1 = [x0,y0,z0]; //start of vector
V2 = [x1,y1,z1]; //end of vector
point = [xx,yy,zz];
_diff = V1 - point;
_diff = V1 - point;
_diff = V1 - point;

_sum =  (_diff*V2 - _diff*V2);
_sum = -(_diff*V2 - _diff*V2);
_sum =  (_diff*V2 - _diff*V2);

_distance = (sqrt(_sum*_sum + _sum*_sum + _sum*_sum) /
sqrt(V2 * V2 + V2 * V2 + V2 * V2 ));``````
I also have this kind of working code that finds the closest point on the line, but it seems to have some mistakes as sometimes it gives weird answers.
GML:
``````//Find nearest point on line to other point. Kind of works?
P1 = [xx,yy,zz];
V1 = [x0,y0,z0]; //start of vector
V2 = [x1,y1,z1]; //end of vector

var u = ((P1 - V1) * (V2 - V1))
+ ((P1 - V1) * (V2 - V1))
+ ((P1 - V1) * (V2 - V1));

var dist = point_distance_3d(x0,y0,z0,x1,y1,z1);
u = u/(dist*dist)

closest_point = V1 + u * (V2 - V1);
closest_point = V1 + u * (V2 - V1);
closest_point = V1 + u * (V2 - V1);``````

I've also found several code non-GML explanations of how to do this, but they are all with vector libraries and I have no idea what they are doing under the hood. Here are two examples I found but can't interpret:

Code:
``````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;
}``````
Code:
``````NearestPointOnLine(Vector3 linePnt, Vector3 lineDir, Vector3 pnt)
{
lineDir.Normalize();//this needs to be a unit vector
var v = pnt - linePnt;
var d = Vector3.Dot(v, lineDir);
return linePnt + lineDir * d;``````
Links for above code:
https://stackoverflow.com/questions/9368436/3d-perpendicular-point-on-line-from-3d-point
https://stackoverflow.com/questions/51905268/how-to-find-closest-point-on-linepublic static Vector3

I would appreciate any help. I've been coming back to this for over a week now. (Generous upvotes if that is any incentive) Thanks!

#### FrostyCat

##### Member
The main driver of this is the vector dot product, which is a measure of how much a vector points in the same direction as another vector. An immediate application of this is the vector projection (the shadow of a vector when mapped flat onto another), and the formulas you observed are basically the ray's starting point plus the projection.

An equivalent in GML is this:
GML:
``````///@func nearestPointOnLine(ox, oy, oz, rx, ry, rz, px, py, pz)
var ox = argument0,
oy = argument1,
oz = argument2,
rx = argument3,
ry = argument4,
rz = argument5,
px = argument6,
py = argument7,
pz = argument8;

// Normalize the ray vector
var rMag = point_distance_3d(0, 0, 0, rx, ry, rz);
rx /= rMag;
ry /= rMag;
rz /= rMag;

// Calculate the pointing vector (origin to point)
var opx = px-ox,
opy = py-oy,
opz = pz-oz;

// Dot product
var dp = dot_product_3d(rx, ry, rz, opx, opy, opz);

// Result: o+(r'.(p-o))r'
return [ox+dp*rx, oy+dp*ry, oz+dp*rz];``````
Edit (2020-04-08): Made a mistake in the formula before, now fixed.

Please, don't touch 3D without the basics of vector geometry and linear algebra. Learn what vector addition/subtraction, scalar-vector multiplication, dot product, cross product, matrix multiplication, and homogeneous coordinates are. If you aren't speaking the lingo, you're wasting everyone's time.

Last edited:
• • IndianaBones and RujiK

#### NightFrost

##### Member
A little off topic, and I don't know what your level of familiarity with the subject is, but in regards to linear algebra, this video series I've been watching seems a very good introduction to it.