local function u(u,t,P)local U,b,q,T=unpack(u.Coefficients)local x=(b[t]+(2*q[t])*P)+((3*T[t])*P)*P return x.Magnitude end local function t(t,P,U)local b=U/SIMPSON_N local q,T,x=u(t,P,U),0,0 for U=0,SIMPSON_N-1,1 do local q=U*b if U%2==0 then x=x+u(t,P,q)else T=T+u(t,P,q)end end return(b*((q+2*x)+4*T))/3 end local function P(u,t,P)local U=#u local b,q,T,x={unpack(u)},{},{},{}local k={}k[1]=3*(b[2]-b[1])-3*t k[U]=3*P-3*(b[U]-b[U-1])for u=2,U-1,1 do k[u]=3*((b[u+1]-2*b[u])+b[u-1])end local E,B,a={2},{.5},{k[1]/2}for u=2,U-1,1 do E[u]=4-B[u-1]B[u]=1/E[u]a[u]=(k[u]-a[u-1])/E[u]end E[U]=2-B[U-1]a[U]=(k[U]-a[U-1])/E[U]T[U]=a[U]for t=U-1,1,-1 do T[t]=a[t]-B[t]*T[t+1]x[t]=(T[t+1]-T[t])/3 q[t]=((u[t+1]-u[t])-T[t])-x[t]end return b,q,T,x end local function U(u)local t=#u local P,U,b,q={unpack(u)},{},{},{}local T={}for u=2,t-1,1 do T[u]=3*((P[u+1]-2*P[u])+P[u-1])end local x=Vector3.new(0,10,0)local k,E,B={1},{0},{ZERO}k[t],B[t],b[t]=1,ZERO,ZERO for u=2,t-1,1 do k[u]=4-E[u-1]E[u]=1/k[u]B[u]=(T[u]-B[u-1])/k[u]end for t=t-1,1,-1 do b[t]=B[t]-E[t]*b[t+1]q[t]=(b[t+1]-b[t])/3 U[t]=((u[t+1]-u[t])-b[t])-q[t]end return P,U,b,q end


local function arcLengthIntegrand(self, spline, t)
	local a, b, c, d = unpack(self.Coefficients)
	local dv = b[spline] + 2*c[spline]*t + 3*d[spline]*t*t
	return dv.Magnitude
end

local function integrate(self, spline, t)
	local h = t / SIMPSON_N
	local xi0, xi1, xi2 = arcLengthIntegrand(self, spline, t), 0, 0
	
	for i = 0, SIMPSON_N - 1 do
		local x = i*h
		if (i % 2 == 0) then
			xi2 = xi2 + arcLengthIntegrand(self, spline, x)
		else
			xi1 = xi1 + arcLengthIntegrand(self, spline, x)
		end
	end
	
	return h * (xi0 + 2*xi2 + 4*xi1) / 3
end

local function clampedCubicSpline(p, fpo, fpn)
	local n = #p
	local a, b, c, d = {unpack(p)}, {}, {}, {}
	
	local aa = {}
	aa[1] = 3*(a[2] - a[1]) - 3*fpo
	aa[n] = 3*fpn - 3*(a[n] - a[n-1])
	
	for i = 2, n - 1 do
		aa[i] = 3 * (a[i+1] - 2*a[i] + a[i-1])
	end
	
	local l, mu, z = {2}, {0.5}, {aa[1]/2}
	
	for i = 2, n - 1 do
		l[i] = 4 - mu[i-1]
		mu[i] = 1 / l[i]
		z[i] = (aa[i] - z[i-1]) / l[i]
	end
	
	l[n] = 2 - mu[n-1]
	z[n] = (aa[n] - z[n-1]) / l[n]
	c[n] = z[n]
	
	for j = n - 1, 1, -1 do
		c[j] = z[j] - mu[j]*c[j+1]
		d[j] = (c[j+1] - c[j]) / 3
		b[j] = p[j+1] - p[j] - c[j] - d[j]
	end
	
	return a, b, c, d
end

local function naturalCubicSpline(p)
	local n = #p
	local a, b, c, d = {unpack(p)}, {}, {}, {}
	
	local aa = {}
	
	for i = 2, n - 1 do
		aa[i] = 3 * (a[i+1] - 2*a[i] + a[i-1])
	end
	
	local start = Vector3.new(0, 10, 0)
	local l, mu, z = {1}, {0}, {ZERO}
	l[n], z[n], c[n] = 1, ZERO, ZERO

	for i = 2, n - 1 do
		l[i] = 4 - mu[i-1]
		mu[i] = 1 / l[i]
		z[i] = (aa[i] - z[i-1]) / l[i]
	end
	
	for j = n - 1, 1, -1 do
		c[j] = z[j] - mu[j]*c[j+1]
		d[j] = (c[j+1] - c[j]) / 3
		b[j] = p[j+1] - p[j] - c[j] - d[j]
	end
	
	return a, b, c, d
end
