There is my try to make railway track, where it's path is defined as love.graphics's line.
Used functions:
Get offset polyline - the right and left rails are just the same line as defined, but with offset
Get Points Along Line - every tie must be on the same distance, but the defined polyline can have long or short segments.
Code: Select all
-- gives points on the line every gap; also returns tangents in this points
function get_points_along_line (line, gap)
local points = {}
local tangents = {}
local rest = gap/2 -- rest is gap to start point on this section
local x1, y1, x2, y2, dx, dy = line[1],line[2]
for i=3, #line-1, 2 do
x2, y2 = line[i],line[i+1]
dx, dy = x2-x1, y2-y1
local sector_length = (dx*dx+dy*dy)^0.5
if sector_length > rest then
-- rest is always shorter than gap; sector is shorter than rest (or gap)
dx, dy = dx/sector_length, dy/sector_length
while sector_length > rest do
local x, y = x1+rest*dx, y1+rest*dy
table.insert (points, x)
table.insert (points, y)
table.insert (tangents, dx)
table.insert (tangents, dy)
rest = rest + gap
end
else -- no point in this distance
end
-- the tail for the next
rest = rest-sector_length
x1, y1 = x2, y2
end
return points, tangents
end
Code: Select all
-- Offsets the given polyline (line) by offset (offset)
function get_offset_polyline (line, offset, reversed)
local offset_polyline = {}
local loop = is_loop (line)
if reversed then
line = reverse_line (line)
end
if #line == 4 then
local x1, y1 = line[1], line[2]
local x2, y2 = line[3], line[4]
local px1, py1, px2, py2 = get_parallel_segment (x1, y1, x2, y2, offset)
offset_polyline = {px1, py1, px2, py2}
elseif not loop then
local x1, y1, x2, y2 = line[1], line[2], line[3], line[4]
local px1, py1, px2, py2 = get_parallel_segment (x1, y1, x2, y2, offset)
table.insert (offset_polyline, px1)
table.insert (offset_polyline, py1)
for i = 5, #line-1, 2 do
local x3, y3 = line[i], line[i+1]
local px3, py3, px4, py4 = get_parallel_segment (x2, y2, x3, y3, offset)
local x, y = get_intersection (px1, py1, px2, py2, px3, py3, px4, py4, false, 4)
table.insert (offset_polyline, x)
table.insert (offset_polyline, y)
x1, y1, x2, y2 = x2, y2, x3, y3
px1, py1, px2, py2 = px3, py3, px4, py4
end
table.insert (offset_polyline, px2)
table.insert (offset_polyline, py2)
else -- loop
local x1, y1, x2, y2 = line[#line-5], line[#line-4], line[#line-3], line[#line-2]
local px1, py1, px2, py2 = get_parallel_segment (x1, y1, x2, y2, offset)
-- for i = 1, #line-1, 2 do
for i = 1, #line-1, 2 do
local x3, y3 = line[i], line[i+1]
local px3, py3, px4, py4 = get_parallel_segment (x2, y2, x3, y3, offset)
local x, y = get_intersection (px1, py1, px2, py2, px3, py3, px4, py4, false, 4)
table.insert (offset_polyline, x)
table.insert (offset_polyline, y)
x1, y1, x2, y2 = x2, y2, x3, y3
px1, py1, px2, py2 = px3, py3, px4, py4
end
end
if #offset_polyline > 3 then
return offset_polyline
end
end