## [SOLVED] Math: Shortest distance from point to line (EDITED)

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

### Re: [Help] Math: Shortest distance from point to line (EDITE

Ref wrote:Saw the typo and after correction seems to work for me.
Question:
Easy to find closest-point-on-line but pretty mess to get closest-point-on-line-segment.
Do you have a 'neat' way of doing this?
This is the 'neatest' I can come up with:

Code: Select all

function ClosestPointOnLineSegment(px,py,x1,y1,x2,y2)
local dx,dy = x2-x1,y2-y1
local length = math.sqrt(dx*dx+dy*dy)
dx,dy = dx/length,dy/length
local posOnLine = math.min(length, math.max(0,dx*(px-x1) + dy*(py-y1)))
return x1+posOnLine*dx,x2+posOnLine*dy
end
The only difference to a closest-point-on-line-calculation is the clamping of the posOnLine. This is a coordinate along the line segment. If the point has to be on the line segment, then this coordinates has to be between zero and length.
XHH
Citizen
Posts: 85
Joined: Thu Jun 20, 2013 6:43 pm
Location: US
Contact:

### Re: [Help] Math: Shortest distance from point to line (EDITE

Sorry that didn't work. But I did figure out how to do it! Should I post the solution?
I like to draw and program davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

### Re: [Help] Math: Shortest distance from point to line (EDITE

If you want to. The whole point of the forums is to help people out. It would help somebody with the same problem as you.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Ref
Party member
Posts: 701
Joined: Wed May 02, 2012 11:05 pm

### Re: [Help] Math: Shortest distance from point to line (EDITE

Mr. Typo again! try changing:

Code: Select all

return x1+posOnLine*dx,x2+posOnLine*dy

to

Code: Select all

return x1+posOnLine*dx,y1+posOnLine*dy

Haven't tried to test it too much yet.
XHH
Citizen
Posts: 85
Joined: Thu Jun 20, 2013 6:43 pm
Location: US
Contact:

### Re: [Help] Math: Shortest distance from point to line (EDITE

Here's my code. You just need to use distLine(LINE,POINT). I was hesitant to post this because I used it in Python. It can be easily changed back to Lua using keywords like function and local.

Code: Select all

#Compute the distance from LINE(x1,y1,x2,y2) to POINT(x,y)

def distLine(line,point):
A,B = [line,line],[line,line]
C = point
if self.distance(A,B) != 0:
dist = cross(A,B,C)/self.distance(A,B)
else:
dist = self.cross(A,B,C/1)
dot1 = dot(A,B,C)
if dot1 > 0:return distance(B,C)
dot2 = dot(B,A,C)
if dot2 > 0:return distance(A,C)
return abs(dist)

def dot(A,B,C):
AB,BC=[0,0],[0,0]

AB = B-A
AB = B-A
BC = C-B
BC = C-B
dot = AB * BC + AB * BC
return dot

#Compute the cross product AB x AC
def cross(A,B,C):
AB,AC = [0,0],[0,0]

AB = B-A
AB = B-A
AC = C-A
AC = C-A
cross = AB * AC - AB * AC
return cross

#Compute the distance from A to B
def distance(A,B):
d1 = A - B
d2 = A - B
return math.sqrt(d1*d1+d2*d2)

I like to draw and program Ref
Party member
Posts: 701
Joined: Wed May 02, 2012 11:05 pm

### Re: [SOLVED] Math: Shortest distance from point to line (EDI

I think Micha's code is pretty neat.
Attachments closest_point2.love
simple test of Micha' code
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

### Re: [SOLVED] Math: Shortest distance from point to line (EDI

Thanks Ref. I definitely go for neatness, whenever possible darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

### Re: [SOLVED] Math: Shortest distance from point to line (EDITED)

I've googled it a lot of times, my solution:

Code: Select all

local function distPointToLine(px,py,x1,y1,x2,y2) -- point, start and end of the segment
local dx,dy = x2-x1,y2-y1
local length = math.sqrt(dx*dx+dy*dy)
dx,dy = dx/length,dy/length
local p = dx*(px-x1)+dy*(py-y1)
if p < 0 then
dx,dy = px-x1,py-y1
return math.sqrt(dx*dx+dy*dy), x1, y1 -- distance, nearest point
elseif p > length then
dx,dy = px-x2,py-y2
return math.sqrt(dx*dx+dy*dy), x2, y2 -- distance, nearest point
end
return math.abs(dy*(px-x1)-dx*(py-y1)), x1+dx*p, y1+dy*p -- distance, nearest point
end
So you can get (and highlight) the nearest segment of a polyline:

Code: Select all

function nearest_sector_in_line (x, y, line)
local x1, y1, x2, y2, min_dist
local ax,ay = line, line
for j = 3, #line-1, 2 do
local bx,by = line[j], line[j+1]
local dist = distPointToLine(x,y,ax,ay,bx,by)
if not min_dist or dist < min_dist then
min_dist = dist
x1, y1, x2, y2 = ax,ay,bx,by
end
ax, ay = bx, by
end
--	love.graphics.line(x1, y1, x2, y2)
return x1, y1, x2, y2
end
Attachments 2021-09-18T10_46_18-Untitled.png (29.45 KiB) Viewed 2437 times nearest-sector-01.love
Last edited by darkfrei on Tue Oct 05, 2021 7:38 pm, edited 1 time in total. Falling in LÖVE I Löve Lua and Love2D
darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

### Re: [SOLVED] Math: Shortest distance from point to line (EDITED)

So, if the drawn line has different colors along the it's length, we can set to every point in window the color of the nearest sector of this line:

Code: Select all

function get_red_blue_gradient_color (t) -- t is between 0 as red to 1 as blue
local r = 2-4*t
local g = t < 1/2 and 4*t or 4-4*t
local b = -2 + 4*t
r = math.min(math.max(0, r), 1)
g = math.min(math.max(0, g), 1)
b = math.min(math.max(0, b), 1)
return {r^0.5,g^0.5,b^0.5,1}
end
Attachments nearest-sector-02-line.png (25.98 KiB) Viewed 2432 times nearest-sector-02-fields.png (90.78 KiB) Viewed 2432 times nearest-sector-02.love Falling in LÖVE 