# 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[0] = V1[0] - point[0];
_diff[1] = V1[1] - point[1];
_diff[2] = V1[2] - point[2];

_sum[0] =  (_diff[1]*V2[2] - _diff[2]*V2[1]);
_sum[1] = -(_diff[0]*V2[2] - _diff[2]*V2[0]);
_sum[2] =  (_diff[0]*V2[1] - _diff[1]*V2[0]);

_distance = (sqrt(_sum[0]*_sum[0] + _sum[1]*_sum[1] + _sum[2]*_sum[2]) /
sqrt(V2[0] * V2[0] + V2[1] * V2[1] + V2[2] * V2[2] ));``````
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[0] - V1[0]) * (V2[0] - V1[0]))
+ ((P1[1] - V1[1]) * (V2[1] - V1[1]))
+ ((P1[2] - V1[2]) * (V2[2] - V1[2]));

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

closest_point[0] = V1[0] + u * (V2[0] - V1[0]);
closest_point[1] = V1[1] + u * (V2[1] - V1[1]);
closest_point[2] = V1[2] + u * (V2[2] - V1[2]);``````

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;``````
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:

#### 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.