Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --n is number of elements
- --d is damping (0 to inf, 1 is standard)
- --s is speed (0 to inf)
- local spring = {}
- local tick = tick
- local setmt = setmetatable
- local cos = math.cos
- local sin = math.sin
- local e = 2.718281828459045
- function spring.new(i, d, s)
- local null = 0*i
- local t0 = tick()
- local p0 = i
- local v0 = null
- local p1 = i
- local d = d or 1
- local s = s or 1
- local self = {}
- local meta = {}
- local function getpv(w)
- local t = s*(w - t0)
- local d2 = d*d
- local h, si, co
- if d2 < 1 then
- h = (1 - d2)^0.5
- local exp = e^(-d*t)/h
- co, si = exp*cos(h*t), exp*sin(h*t)
- elseif d2 == 1 then
- h = 1
- local exp = e^(-d*t)/h
- co, si = exp, exp*t
- else
- h = (d2 - 1)^0.5
- local u = e^((-d + h)*t)/(2*h)
- local v = e^((-d - h)*t)/(2*h)
- co, si = u + v, u - v
- end
- local a0 = h*co + d*si
- local a1 = 1 - (h*co + d*si)
- local a2 = si/s
- local b0 = -s*si
- local b1 = s*si
- local b2 = h*co - d*si
- return a0*p0 + a1*p1 + a2*v0,
- b0*p0 + b1*p1 + b2*v0
- end
- function self.init(p, v, t)
- t0 = tick()
- p0 = p or null
- v0 = v or null
- p1 = t or p or null
- end
- function meta:__index(index)
- local w = tick()
- if index=="p" then
- local p, v = getpv(w)
- return p
- elseif index=="v" then
- local p, v = getpv(w)
- return v
- elseif index=="t" then
- return p1
- elseif index=="d" then
- return d
- elseif index=="s" then
- return s
- elseif index=="a" then
- local p, v = getpv(w)
- local a = s*s*(p1 - p) - 2*s*d*v
- return a
- end
- end
- function meta:__newindex(index, value)
- local w = tick()
- p0, v0 = getpv(w)
- t0 = w
- if index=="p" then
- p0 = value or null
- elseif index=="v" then
- v0 = value or null
- elseif index=="t" then
- p1 = value or null
- elseif index=="d" then
- d = value or 1
- elseif index=="s" then
- s = value or 1
- end
- end
- self.init()
- return setmt(self, meta)
- end
- return spring
Add Comment
Please, Sign In to add comment