How to tween a parabola?
- Gunroar:Cannon()
- Party member
- Posts: 1088
- Joined: Thu Dec 10, 2020 1:57 am
How to tween a parabola?
I'm just wondering if there's anyway to make an object reach a target, in a specific time, using tweening/a tweening lib(like Chrono) but in an upward curve.
The way I do it involves making it tween in 3 different steps. Up a little+a little x, straight+x, down + a little x. Is there a formula for this or something simpler?
The way I do it involves making it tween in 3 different steps. Up a little+a little x, straight+x, down + a little x. Is there a formula for this or something simpler?
Re: How to tween a parabola?
,You can use quadratic bezier curve, it's true parabola.
Re: How to tween a parabola?
Code: Select all
local duration = 2 -- in seconds
local t = -1
local function lerp(a, b, t)
return t < 0.5 and a + (b - a) * t or b - (b - a) * (1 - t)
end
local function tween_parabola(a, b, t)
return lerp(a, b, 1-(t*2-1)^2)
end
local dt
function love.update(_dt)
dt = _dt
end
function love.draw()
if t >= 0 then
love.graphics.circle("fill", lerp(100, 700, t), tween_parabola(550, 50, t), 5)
t = t + dt / duration
if t > 1 then t = 1 end
end
end
function love.keypressed(k)
if k == "space" then t = 0 end
if k == "escape" then return love.event.quit() end
end
- Gunroar:Cannon()
- Party member
- Posts: 1088
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to tween a parabola?
Thanks for the formula, pg!
I used it fine (for a bomb toss, heheh), though I have a problem which I want to fix up now because I had a time limit for a project so I managed before.
My timer lib, I kind of understand it's tweening functions, but I can't figure out how to add that parabola into one of it's functions (e.g. quad,sine,bounce)
Its list of functions look like
t.linear = function(s) return s end
t.quad = function(s) return s*s end
t.cubic = function(s) return s*s*s end
t.quart = function(s) return s*s*s*s end
t.quint = function(s) return s*s*s*s*s end
t.sine = function(s) return 1-math.cos(s*math.pi/2) end
t.expo = function(s) return 2^(10*(s-1)) end
t.circ = function(s) return 1-math.sqrt(1-s*s) end
t.back = function(s, bounciness) bounciness = bounciness or 1.70158; return s*s*((bounciness+1)*s - bounciness) end
t.bounce = function(s) local a, b = 7.5625, 1/2.75; return math.min(a*s^2, a*(s-1.5*b)^2 + 0.75, a*(s-2.25*b)^2 + 0.9375, a*(s-2.625*b)^2 + 0.984375) end
t.elastic = function(s, amp, period) amp, period = amp and math.max(1, amp) or 1, period or 0.3; return (-amp*math.sin(2*math.pi/period*(s-1) - math.asin(1/amp)))*2^(10*(s-1)) end
And only have one compulsory argument, s.
I used it fine (for a bomb toss, heheh), though I have a problem which I want to fix up now because I had a time limit for a project so I managed before.
My timer lib, I kind of understand it's tweening functions, but I can't figure out how to add that parabola into one of it's functions (e.g. quad,sine,bounce)
Code: Select all
function Timer:tween(delay, subject, target, method, after, tag, ...)
if type(after) == 'string' then tag, after = after, nil
elseif type(after) == 'function' then tag = UUID()
else tag = tag or UUID() end
self:cancel(tag)
self.timers[tag] = {type = 'tween', time = 0, delay = self:__getResolvedDelay(delay), subject = subject, target = target, method = method or "linear", after = after or null,
args = {...}, last_s = 0, payload = self:__tweenCollectPayload(subject, target, {})}
return tag
end
local t = {}
t.out = function(f) return function(s, ...) return 1 - f(1-s, ...) end end
t.chain = function(f1, f2) return function(s, ...) return (s < 0.5 and f1(2*s, ...) or 1 + f2(2*s-1, ...))*0.5 end end
t.linear = function(s) return s end
t.quad = function(s) return s*s end
t.cubic = function(s) return s*s*s end
t.quart = function(s) return s*s*s*s end
t.quint = function(s) return s*s*s*s*s end
t.sine = function(s) return 1-math.cos(s*math.pi/2) end
t.expo = function(s) return 2^(10*(s-1)) end
t.circ = function(s) return 1-math.sqrt(1-s*s) end
t.back = function(s, bounciness) bounciness = bounciness or 1.70158; return s*s*((bounciness+1)*s - bounciness) end
t.bounce = function(s) local a, b = 7.5625, 1/2.75; return math.min(a*s^2, a*(s-1.5*b)^2 + 0.75, a*(s-2.25*b)^2 + 0.9375, a*(s-2.625*b)^2 + 0.984375) end
t.elastic = function(s, amp, period) amp, period = amp and math.max(1, amp) or 1, period or 0.3; return (-amp*math.sin(2*math.pi/period*(s-1) - math.asin(1/amp)))*2^(10*(s-1)) end
function Timer:__tween(method, ...)
if method == 'linear' then return t.linear(...)
elseif method:find('in%-out%-') then return t.chain(t[method:sub(8, -1)], t.out(t[method:sub(8, -1)]))(...)
elseif method:find('out%-in%-') then return t.chain(t.out(t[method:sub(8, -1)]), t[method:sub(8, -1)])(...)
elseif method:find('out%-') then return t.out(t[method:sub(5, -1)])(...)
elseif method:find('in%-') then return t[method:sub(4, -1)](...) end
end
function Timer:__tweenCollectPayload(subject, target, out)
for k, v in pairs(target) do
local ref = subject[k]
if ref==nil then
else
assert(type(v) == type(ref), 'Type mismatch in field "' .. k .. '".')
if type(v) == 'table' then self:__tweenCollectPayload(ref, v, out)
else
local ok, delta = pcall(function() return (v-ref)*1 end)
assert(ok, 'Field "' .. k .. '" does not support arithmetic operations.')
out[#out+1] = {subject, k, delta}
end
end
end
return out
end
function Timer:update(dt)
for tag, timer in pairs(self.timers) do
...
elseif timer.type == 'tween' then
local s = self:__tween(timer.method, math.min(1, timer.time/timer.delay), unpack(timer.args or {}))
local ds = s - timer.last_s
timer.last_s = s
for _, info in ipairs(timer.payload) do
local ref, key, delta = unpack(info)
ref[key] = ref[key] + delta*ds
end
...
end
end
end
t.linear = function(s) return s end
t.quad = function(s) return s*s end
t.cubic = function(s) return s*s*s end
t.quart = function(s) return s*s*s*s end
t.quint = function(s) return s*s*s*s*s end
t.sine = function(s) return 1-math.cos(s*math.pi/2) end
t.expo = function(s) return 2^(10*(s-1)) end
t.circ = function(s) return 1-math.sqrt(1-s*s) end
t.back = function(s, bounciness) bounciness = bounciness or 1.70158; return s*s*((bounciness+1)*s - bounciness) end
t.bounce = function(s) local a, b = 7.5625, 1/2.75; return math.min(a*s^2, a*(s-1.5*b)^2 + 0.75, a*(s-2.25*b)^2 + 0.9375, a*(s-2.625*b)^2 + 0.984375) end
t.elastic = function(s, amp, period) amp, period = amp and math.max(1, amp) or 1, period or 0.3; return (-amp*math.sin(2*math.pi/period*(s-1) - math.asin(1/amp)))*2^(10*(s-1)) end
And only have one compulsory argument, s.
Re: How to tween a parabola?
I don't know what the tweening function is, but
Where a is acceleration (gravity), b is initial velocity and c is initial position.
X is some changing value, for example time or horizontal length from starting position.
Code: Select all
t.parab = function (x, a, b, c) return a*x*x+b*x+c end
X is some changing value, for example time or horizontal length from starting position.
- Gunroar:Cannon()
- Party member
- Posts: 1088
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to tween a parabola?
Oh, and I just make a,b and c have a default value (so the equivalent of "s" in my timer lib is x here, nice). Hopefully, his explains it more. But what's c, a constant?darkfrei wrote: ↑Tue Aug 30, 2022 1:12 pmWhere a is acceleration (gravity), b is initial velocity and c is initial position.Code: Select all
t.parab = function (x, a, b, c) return a*x*x+b*x+c end
X is some changing value, for example time or horizontal length from starting position.
Re: How to tween a parabola?
It'value of initial high. The value, that will be returned by x = 0.Gunroar:Cannon() wrote: ↑Tue Aug 30, 2022 1:21 pmOh, and I just make a,b and c have a default value (so the equivalent of "s" in my timer lib is x here, nice). Hopefully, his explains it more. But what's c, a constant?darkfrei wrote: ↑Tue Aug 30, 2022 1:12 pmWhere a is acceleration (gravity), b is initial velocity and c is initial position.Code: Select all
t.parab = function (x, a, b, c) return a*x*x+b*x+c end
X is some changing value, for example time or horizontal length from starting position.
https://www.desmos.com/calculator/zukjgk9iry
And
https://www.desmos.com/calculator/8keeh1pt5l
Re: How to tween a parabola?
See the formula I used in tween_parabola:
1-(t*2-1)^2
So:
1-(t*2-1)^2
So:
Code: Select all
t.parab = function(s) return 1-(s*2-1)^2 end
- Gunroar:Cannon()
- Party member
- Posts: 1088
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to tween a parabola?
Yes, thanks too!!
- Gunroar:Cannon()
- Party member
- Posts: 1088
- Joined: Thu Dec 10, 2020 1:57 am
Re: How to tween a parabola?
I think when the (Y) value of the goal is bigger than the (Y) value of the origin it has an opposite arc and reversing the at. just makes it wobble. Anyway to always make the arc one that goes up and back down no matter what (while still using tweening)?pgimeno wrote: ↑Tue Aug 30, 2022 8:02 pm See the formula I used in tween_parabola:
1-(t*2-1)^2
So:Code: Select all
t.parab = function(s) return 1-(s*2-1)^2 end
Who is online
Users browsing this forum: No registered users and 61 guests