function CubicSpline.AtTime(q,F)local Z=#q.Points local s=math.clamp(F,0,Z)local Q=math.floor(s)local N=s-Q local t=Q%(Z-1)+1 local T,b,h,z=unpack(q.Coefficients)return((T[t]+b[t]*N)+(h[t]*N)*N)+((z[t]*N)*N)*N end function CubicSpline.AtPercentage(q,F)local Z=F*q.TotalLength local s=q.Lengths if F>=1 then return q.Points[#q.Points]end local Q=1 while Z>s[Q]do Z=Z-s[Q]Q=Q+1 end local N=Z/s[Q]for F=1,NEWTON_N,1 do N=N-(integrate(q,Q,N)-Z)/arcLengthIntegrand(q,Q,N)end return q:AtTime((Q-1)+N)end



function CubicSpline:AtTime(t)
	local n = #self.Points
	local ct = math.clamp(t, 0, n)
	local floor = math.floor(ct)
	local ft = ct - floor
	
	local spline = (floor % (n - 1)) + 1
	local a, b, c, d = unpack(self.Coefficients)

	return a[spline] + b[spline]*ft + c[spline]*ft*ft + d[spline]*ft*ft*ft
end

function CubicSpline:AtPercentage(p)
	local t = p * self.TotalLength
	local lengths = self.Lengths
	
	if (p >= 1) then
		return self.Points[#self.Points]
	end
	
	local spline = 1
	while (t > lengths[spline]) do
		t = t - lengths[spline]
		spline = spline + 1
	end

	local s = t / lengths[spline]
	
	for i = 1, NEWTON_N do
		s = s - (integrate(self, spline, s) - t) / arcLengthIntegrand(self, spline, s)
	end
	
	return self:AtTime((spline - 1) + s)
end
