nearest

Useful functions to find the nearest.

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 in 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 findNearestPointInSegment(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