Skip to content

Instantly share code, notes, and snippets.

@Fraktality
Created February 16, 2018 21:18
Show Gist options
  • Save Fraktality/1033625223e13c01aa7144abe4aaf54d to your computer and use it in GitHub Desktop.
Save Fraktality/1033625223e13c01aa7144abe4aaf54d to your computer and use it in GitHub Desktop.
local Spring = {} do
Spring.__index = Spring
local pi = math.pi
local exp = math.exp
local sin = math.sin
local cos = math.cos
local sqrt = math.sqrt
function Spring.new(dampingRatio, frequency, position)
local self = setmetatable({}, Spring)
assert(dampingRatio*frequency >= 0, 'stop that')
self.d = dampingRatio -- damping ratio
self.f = frequency -- nominal frequency
self.g = position -- goal position
self.p = position -- position
self.v = position*0 -- velocity (times 0 so the types match)
return self
end
function Spring:setGoal(g)
self.g = g
end
function Spring:getState()
return self.p, self.v
end
function Spring:step(dt)
local d = self.d
local f = self.f*2*pi
local g = self.g
local p = self.p
local v = self.v
local offset = p - g
local decay = exp(-dt*d*f)
-- Given:
-- f^2*(x[dt] - g) + 2*d*f*x'[dt] + x''[dt] = 0,
-- x[0] = p,
-- x'[0] = v
-- Solve for x[dt], x'[dt]
if d == 1 then -- critically damped
self.p = (v*dt + offset*(f*dt + 1))*decay + g
self.v = (v - f*dt*(offset*f + v))*decay
elseif d < 1 then -- underdamped
local c = sqrt(1 - d*d)
local i = cos(f*c*dt)
local j = sin(f*c*dt)
self.p = (i*offset + j*(v + d*f*offset)/(f*c))*decay + g
self.v = (i*c*v - j*(v*d + f*offset))*decay/c
elseif d > 1 then -- overdamped
local c = sqrt(d*d - 1)
local r1 = -f*(d - c)
local r2 = -f*(d + c)
local co2 = (v - r1*offset)/(2*f*c)
local co1 = offset - co2
local e1 = co1*exp(r1*dt)
local e2 = co2*exp(r2*dt)
self.p = e1 + e2 + g
self.v = r1*e1 + r2*e2
end
end
end
return Spring
@Cesare0328
Copy link

hmmmm yeah roblox defenetily didnt steal your code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment