local function A(A,m)local Y=m-A if type(Y)=="\110\117\109\098\101\114"then return math.abs(Y)end return Y.Magnitude end local m={}m.__index=m m.__type="\083\112\114\105\110\103"function m.__tostring(A)return m.__type end function m.new(A,Y,x,a)local s=setmetatable({},m)s.instant=false s.marginOfError=1e-06 x=x or 1 local t=(Y*Y)/(((4*A)*x)*x)s.k=A/t s.d=-Y/t s.x=a s.t=a s.v=a*0 return s end function m.Update(Y,m)if not Y.instant then local x,a,s,t,I=Y.t,Y.k,Y.d,Y.x,Y.v local Q=a*(x-t)+I*s local Z=I+Q*(m/2)local W=a*(x-(t+I*(m/2)))+Z*s local D=I+W*(m/2)local o=a*(x-(t+Z*(m/2)))+D*s local P=I+o*m local q=t+((I+2*(Z+D))+P)*(m/6)Y.x,Y.v=q,I+(((Q+2*(W+o))+a*(x-(t+D*m)))+P*s)*(m/6)if A(q,Y.t)>Y.marginOfError then return q end end Y.x,Y.v=Y.t,Y.v*0 return Y.x end return m
-- CONSTANTS

-- Private Functions

local function getAbsDist(a, b)
	local d = b - a
	if (type(d) == "number") then
		return math.abs(d)
	end
	return d.Magnitude
end

-- Class

local SpringClass = {}
SpringClass.__index = SpringClass
SpringClass.__type = "Spring"

function SpringClass:__tostring()
	return SpringClass.__type
end

-- Public Constructors

function SpringClass.new(stiffness, dampingCoeff, dampingRatio, initialPos)
	local self = setmetatable({}, SpringClass)
	
	self.instant = false
	self.marginOfError = 1E-6

	dampingRatio = dampingRatio or 1
	local m = dampingCoeff*dampingCoeff/(4*stiffness*dampingRatio*dampingRatio)
	self.k = stiffness/m
	self.d = -dampingCoeff/m
	self.x = initialPos
	self.t = initialPos
	self.v = initialPos*0

	return self
end

-- Public Methods

function SpringClass:Update(dt)
	if (not self.instant) then
		local t, k, d, x0, v0 = self.t, self.k, self.d, self.x, self.v
		local a0 = k*(t - x0) + v0*d
		local v1 = v0 + a0*(dt/2)
		local a1 = k*(t - (x0 + v0*(dt/2))) + v1*d
		local v2 = v0 + a1*(dt/2)
		local a2 = k*(t - (x0 + v1*(dt/2))) + v2*d
		local v3 = v0 + a2*dt
		local x4 = x0 + (v0 + 2*(v1 + v2) + v3)*(dt/6)
		self.x, self.v = x4, v0 + (a0 + 2*(a1 + a2) + k*(t - (x0 + v2*dt)) + v3*d)*(dt/6)
		
		if (getAbsDist(x4, self.t) > self.marginOfError) then
			return x4
		end
	end
	
	self.x, self.v = self.t, self.v*0
	return self.x
end

--

return SpringClass