# How to go about projecting a point onto a line using a direction!

### Godot Version

4.2.stable.mono.official

### Question

How to go about projecting a point onto a line using a direction!

Effectively I have this function that takes in a point in 3D space, a line start and end (both in 3D space) and then gives out the closest point on that line.

``````func project_point_on_line(P : Vector3, A : Vector3, B : Vector3) -> Vector3:

var line_direction = B - A
var line_length = line_direction.length()
line_direction = line_direction.normalized()

var change = P-A

var project_length : float = clampf(
change.dot(line_direction), 0, line_length)

return A + line_direction*project_length # this all works as expected!
``````

And that function above works as expected! But I want instead a function that takes in all that plus a general direction and then gives us the closest point on the line in that general direction rather than the exact closest point.

``````func project_point_on_line_within_direction(P : Vector3, A : Vector3, B : Vector3, Project_Dir : Vector3) -> Vector3:
# code that does all that somehow.
``````

But I am not very good at this sort of thing, so I ask you! If you could help with this issue, please do!
Any help would be very appreciated!

The term you want to search for is â€śline intersectionâ€ť - you have two lines, the one defined by `A` and `B`, and the one defined by `P` and `Project_Dir`, although the latter doesnâ€™t have an end point. So what youâ€™re looking for isnâ€™t projection, but finding the intersection.

1 Like

For the implementation I need, the P and Project_Dir arenâ€™t going to be always able to intersect with the line.

But there might be some sort of way to adjust Project_Dir so it does intersect every time so projecting wouldnâ€™t be necessary but I wouldnâ€™t know of one.

not a math wiz this is what i would do. it took several 25 oz rolling rocks before i told myself i knew what you were asking

1 Like

Thats a good way to find the closest point on the line! But I already got the function that gets that done already

``````func project_point_on_line(P : Vector3, A : Vector3, B : Vector3) -> Vector3:

var line_direction = B - A
var line_length = line_direction.length()
line_direction = line_direction.normalized()

var change = P-A

var project_length : float = clampf(
change.dot(line_direction), 0, line_length)

return A + line_direction*project_length # this all works as expected
``````

Iâ€™m asking for a function that like gets our point and smacks it onto the line in the given general direction

Assume the line starts with A and ends with B, your general direction starts with P and ends with Q, then your target closest point should be:

``````var line_direction = (B - A).normalized()
var projected_p = (P - A).dot(line_direction)
var projected_q = (Q - P).dot(line_direction)
var closest = A + (projected_p + projected_q) * line_direction
``````

To check if the closest point is on the line, just check if (project_p + project_q) is between 0 and 1.
I donâ€™t know if I comprehend your requirements.

1 Like

Ah, sorry, you should check if (project_p + project_q) is between 0 and (B - A).length()

1 Like

It worked! heres the code, after some tinkering!

``````func project_point_on_line_within_direction(P : Vector3, A : Vector3, B : Vector3, Project_Dir : Vector3) -> Vector3:
var Q = P + Project_Dir.normalized()

var line_direction = B - A
var line_length = line_direction.length()
line_direction = line_direction.normalized()

var projected_p = (P - A).dot(line_direction)
var projected_q = (Q - P).dot(line_direction)
var closest = A + (clampf(
(projected_p + projected_q),
0, line_length)+clampf(
projected_p, # it takes both solutions and takes the middle of them!
0, line_length))/2 * line_direction

return closest
``````

It still isnâ€™t exact but it works and it does well!
So thank you a lot math wizard man!
( and everyone else who helped too `:)` )

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.