Railway Track

Show off your games, demos and other (playable) creations.
Post Reply
User avatar
darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

Railway Track

Post by darkfrei »

Hi all!

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
Attachments
2021-09-18T19_52_49-Untitled.png
2021-09-18T19_52_49-Untitled.png (24.15 KiB) Viewed 3619 times
2021-09-18T22_50_34.png
2021-09-18T22_50_34.png (129.88 KiB) Viewed 3619 times
railway-track-01.love
(2.59 KiB) Downloaded 76 times
Last edited by darkfrei on Sun Sep 19, 2021 10:23 am, edited 1 time in total.
:awesome: Falling in LÖVE :awesome:
I Löve Lua and Love2D
togFox
Party member
Posts: 384
Joined: Sat Jan 30, 2021 9:46 am

Re: Railway Track

Post by togFox »

Nice. I'll not sure where I would start with such a problem!
User avatar
BrotSagtMist
Citizen
Posts: 62
Joined: Fri Aug 06, 2021 10:30 pm

Re: Railway Track

Post by BrotSagtMist »

Is it necessary to get this offset?
You could just draw two lines of different width on top of each other i would say.

For the ties it is also possible to draw them short and thick, may be faster.
This would have been a use case for stipple lines, but that setting was removed.
obey
User avatar
darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

Re: Railway Track

Post by darkfrei »

BrotSagtMist wrote: Sun Sep 19, 2021 3:21 am Is it necessary to get this offset?
You could just draw two lines of different width on top of each other i would say.

For the ties it is also possible to draw them short and thick, may be faster.
This would have been a use case for stipple lines, but that setting was removed.
But rails must be above the ties and in the middle between rails must be transparent area, not black thick line.
:awesome: Falling in LÖVE :awesome:
I Löve Lua and Love2D
User avatar
BrotSagtMist
Citizen
Posts: 62
Joined: Fri Aug 06, 2021 10:30 pm

Re: Railway Track

Post by BrotSagtMist »

You can always add another canvas for order and instead of painting you can erase pixels too.
A quick hack in of my approach:
main.lua.zip
(1.85 KiB) Downloaded 82 times
obey
User avatar
darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

Re: Railway Track

Post by darkfrei »

BrotSagtMist wrote: Sun Sep 19, 2021 3:15 pm You can always add another canvas for order and instead of painting you can erase pixels too.
A quick hack in of my approach:
main.lua.zip
Nice! Didn't know that you can erase by writing with the color {0,0,0,0} with color replacing.

Code: Select all

-- new canvas
tmp = love.graphics.newCanvas()
	love.graphics.setCanvas(tmp)
	love.graphics.setColor({0.6,0.8,0.8}) -- rail color
	love.graphics.setLineWidth (rail_width+3) -- three pixels more
	love.graphics.line(line)
	love.graphics.setBlendMode("replace")
	love.graphics.setColor(0,0,0,0) -- black transparent color
	love.graphics.setLineWidth (rail_width-3) -- three pixels less
	love.graphics.line(line) -- each rail is 3 pixels wide now
-- disabling canvas
love.graphics.newCanvas()
love.graphics.setBlendMode("alpha")
:awesome: Falling in LÖVE :awesome:
I Löve Lua and Love2D
User avatar
darkfrei
Party member
Posts: 417
Joined: Sat Feb 08, 2020 11:09 pm

Re: Railway Track

Post by darkfrei »

BrotSagtMist wrote: Sun Sep 19, 2021 3:15 pm You can always add another canvas for order and instead of painting you can erase pixels too.
A quick hack in of my approach:
main.lua.zip
The problem:
Attachments
2021-10-06T16_41_52.png
2021-10-06T16_41_52.png (86.34 KiB) Viewed 2041 times
:awesome: Falling in LÖVE :awesome:
I Löve Lua and Love2D
User avatar
BrotSagtMist
Citizen
Posts: 62
Joined: Fri Aug 06, 2021 10:30 pm

Re: Railway Track

Post by BrotSagtMist »

I dont think trains work like that dude.
Anyway, how do you even want it to look in the end? If you want to get rid of the rail gap you can simply add another canvas and render the rails step by step.
obey
Post Reply

Who is online

Users browsing this forum: No registered users and 27 guests