nearest
Useful functions to find the nearest.
Contents
Nearest point in array of points
-- function to calculate the distance between two points
local function distance(x1, y1, x2, y2)
return math.sqrt((x2 - x1)^2 + (y2 - y1)^2)
end
-- function to find the nearest point from a list of points
function findNearestPointInPoints (points, point)
-- points is array of pairs: {x1, y1, x2, y2, ...}
local minDistance = math.huge
local nearestX, nearestY = nil, nil
for i = 1, #points, 2 do
local x, y = points[i], points[i + 1]
local dist = distance(x, y, point[1], point[2])
if dist < minDistance then
minDistance = dist
nearestX, nearestY = x, y
end
end
return nearestX, nearestY, minDistance
end
Nearest point on line segment
-- function to calculate the distance between two points
local function distance(x1, y1, x2, y2)
return math.sqrt((x2 - x1)^2 + (y2 - y1)^2)
end
-- function to find the nearest point on a segment to the given point
function findNearestPointOnSegment(segment, point)
-- segment is array of pairs: {x1, y1, x2, y2}
local x1, y1, x2, y2 = segment[1], segment[2], segment[3], segment[4]
local px, py = point[1], point[2]
-- vector from the first point of the segment to the second point
local dx, dy = x2 - x1, y2 - y1
-- vector from the first point of the segment to the point
local dx1, dy1 = px - x1, py - y1
-- segment length squared
local segmentLengthSquared = dx * dx + dy * dy
if segmentLengthSquared == 0 then
-- degenerate segment (same point), return the start point
return {x1, y1}, distance(px, py, x1, y1)
end
-- projection of the point onto the line (parameter t)
local t = ((dx1 * dx + dy1 * dy) / segmentLengthSquared)
-- clamp t to be between 0 and 1 to stay within the segment
if t < 0 then
t = 0
elseif t > 1 then
t = 1
end
-- calculate the nearest point on the segment
local nearestX = x1 + t * dx
local nearestY = y1 + t * dy
-- return the nearest point and its distance from the given point
return nearestX, nearestY, distance(px, py, nearestX, nearestY)
end
Nearest point on the polyline
A polyline is a broken line made up of a series of connected line segments.
function findNearestPointOnPolyline(polyline, point)
-- polyline is array of pairs: {x1, y1, x2, y2, ...}
local minDistance = math.huge
local nearestX, nearestY = nil, nil
for i = 1, #polyline - 2, 2 do
-- get segment
local segment = {polyline[i], polyline[i + 1], polyline[i + 2], polyline[i + 3]}
-- find the nearest point on the current segment
-- function findNearestPointOnSegment(segment, point) is above
local px, py, dist = nearestPointOnSegment(segment, point)
-- update the minimum distance and nearest point
if dist < minDistance then
minDistance = dist
nearestX, nearestY = px, py
end
end
return nearestX, nearestY, minDistance
end
Nearest point on the circle
function nearestPointOnCircle(px, py, cx, cy, r)
-- calculate the angle between the point and the center
local theta = math.atan2(py - cy, px - cx)
-- calculate the nearest point on the circle using the angle
local nx = cx + r * math.cos(theta)
local ny = cy + r * math.sin(theta)
return nx, ny
end