Instantly share code, notes, and snippets.

# Fraktality/Spring.lua

Created February 16, 2018 21:18
Star You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 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 commented Apr 6, 2021

hmmmm yeah roblox defenetily didnt steal your code