Spline Generation

Hello.
I am working on a transport tycoon game, one of the features of this game is to be able to draw, lets say a track between three points and it would create a smooth curve, which I dont know how to do

The picture shows above the curve that I want to create between three points, x, y and z

Oh and I haven’t found any documentation on the wiki about this

3 Likes

What you’re looking for is Bezier curves. Search on here and check the wiki - there’s loads of information on it. I think Crazyman12 made a bezier module to create them easily too. Good luck!

2 Likes

There’s also a Bézier Curve wiki tutorial! And this is my Bézier module.

6 Likes

Using what @Fractality_alt did in:
https://devforum.roblox.com/t/cubic-spline-solver/37303?source_topic_id=81431

You can do something similar to by combining his magical functions:



local function calculatePos(x,a,b,c,d)
	return a + x*(b + x*(c + x*d))
end

local function GetHermiteCoefficients(p0, p1, m0, m1)
	return p0, m0, 3*(p1 - p0) - 2*m0 - m1, 2*(p1 - p0) - m0 - m1
end

local function GetCentripetalCRCoefficients(p0, p1, p2, p3)
	return
		p1,
		0.5*(p2 - p0),
		p0 - 2.5*p1 + 2*p2 - 0.5*p3,
		1.5*(p1 - p2) + 0.5*(p3 - p0)
end

--[[
	example:
		
	a_to_b = CatmullRom(a, a, b, c)
	b_to_c = CatmullRom(a, b, c, d)
	c_to_d = CatmullRom(b, c, d, d)
--]]

local v3 = Vector3.new

local points = {
	v3(0,0,0),
	v3(5,0,0),
	v3(2,7,3),
	v3(4,5,6),
}

local new = Instance.new
local pSize = v3(0.2,0.2,0.2)
local size = #points
for i = 1,size-1 do
	local b = points[i]
	local a = points[i-1] or b
	local c = points[i+1] or b
	local d = points[i+2] or c
	
	a,b,c,d = GetCentripetalCRCoefficients(a,b,c,d)
	
	for j = 0,1,0.05 do
		local p = new("Part")
		p.Size = pSize
		p.Anchored = true

		
	
		p.Position = calculatePos(j,a,b,c,d)
		p.Parent = workspace
	end
	
	local p = new("Part")
	p.Size = pSize*2
	p.BrickColor = BrickColor.new("Bright red")
	p.Anchored = true

	p.Position = points[i]
	p.Parent = workspace
end

local p = new("Part")
p.Size = pSize*2
p.BrickColor = BrickColor.new("Bright red")
p.Anchored = true

p.Position = points[size]
p.Parent = workspace
10 Likes

The railfan in me can’t help but point out that transit rail is generally designed with as much straightaway as possible (for which both construction and operational cost are cheapest), and when turns are required, they are done with transitional sections that are most often Euler spirals to minimize the rate of change of centripetal force. You can easily observe this on Google Maps for railway and also highway transitions like exits, on-ramps and interchanges. In practice, this is approximated well with a section of ellipse, which is easier to calculate than the Euler spiral, splines and Bezier curves.

11 Likes

I cant FULLY understand this code without comments, but I can read it

1 Like