Tiled world with smooth movement transitions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
pgimeno
Party member
Posts: 3227
Joined: Sun Oct 18, 2015 2:58 pm

Re: Tiled world with smooth movement transitions

Yeah that derivation is mine. I used an algebra program (isympy) to do the calculations. Basically what you need to do is solve a system of equations, given the following constraints:

- It needs to be a cubic polynomial of the form: y = (x - 1)^2*(x*a + x - 1) + 1 (I just replaced t with 1-x and simplified). 'a' here is the value we want to calculate from the overshoot h.
- It must be 0 when x = 0.
- It must be 1 when x = 1.
- The derivative at x = 1 must be zero (it must be horizontal at that point).
- The derivative at a certain point (initially unknown) between 0 and 1 must also be zero.
- The maximum value must be 1 + desired parameter, which has to be positive so we have overshooting.

The maximum is precisely the Y coordinate of the other point where the derivative is zero. So you have to solve for 'a' in the system of equations that arises from these constraints. The form of the equation already guarantees some of these constraints. like the values at x=0 and x=1 and the derivative at x=1. I can do a full write-up if desired, I'm not doing it right now to not bore other readers
RNavega
Party member
Posts: 103
Joined: Sun Aug 16, 2020 1:28 pm

Re: Tiled world with smooth movement transitions

Ah, very interesting, thanks. I didn't know about Sympy.
darkfrei
Party member
Posts: 735
Joined: Sat Feb 08, 2020 11:09 pm

Re: Tiled world with smooth movement transitions

Is the cubic polynom just a cubic bezier curve?
pgimeno
Party member
Posts: 3227
Joined: Sun Oct 18, 2015 2:58 pm

Re: Tiled world with smooth movement transitions

The curve that RNavega posted in the previous page seems to be a Bézier, but the equation I posted is not. I don't really like Bézier curves for tweening; they have a different interface ({x, y} = f(t) instead of v = f(t)), and you're restricted to polynomials (cubics, normally), so e.g. you can't implement the bouncing ball tweening function, unless they're concatenated, in which case they make it hard to make the movement smooth.

It might be possible to make a Bézier curve that exactly matches the curve I posted; you just have to find parameters that remove the quadratic and cubic terms from the horizontal axis, so that it's linear like this curve is.

Edit: Yes, I've done some math, that's actually easy - just place the first point at 0,0; the last point at 1,1; the first control point's x coordinate at 1/3 and choose the y coordinate to adjust the overshoot, and the second control point at x=2/3, y=1.

Edit2: Just made this with Inkscape:

The middle guides are exactly at 1/3 and 2/3 of the grey square's side. The first control point's y coordinate may be moved at will to adjust the overshoot. That curve is exactly like the formula I posted.
RNavega
Party member
Posts: 103
Joined: Sun Aug 16, 2020 1:28 pm

Re: Tiled world with smooth movement transitions

I looked this up, if you have the 4 control points of the cubic Bezier it's possible to evaluate the y (the interpolated result) based on an x. This x isn't the same as the t parameter, it's more like a vertical ray crossing the curve.

The problem is that the easing formulas will always be faster than doing that, since they're much simpler. Evaluating the Bezier for a certain x requires you to calculate the curve roots for that x using something like Cardano's formula, which is more expensive than the easing formulas, looking at the Blender source responsible for that:
https://github.com/dfelinto/blender/blo ... ve.c#L1571

Edit: and this other resource here with the theory: https://pomax.github.io/bezierinfo/#yforx
pgimeno
Party member
Posts: 3227
Joined: Sun Oct 18, 2015 2:58 pm

Re: Tiled world with smooth movement transitions

RNavega wrote: Thu Sep 08, 2022 12:18 am I looked this up, if you have the 4 control points of the cubic Bezier it's possible to evaluate the y (the interpolated result) based on an x.
Oh, well, right, you can turn it into an easing formula by solving the cubic equation. I didn't even think of it because it's too expensive by my standards; e.g. the calc_outback_param function calculates the solution of a cubic equation, and I recommend the value to be cached and reused because that calculation is expensive.

This approach has another problem - what to do when there are three solutions, that is, three Y coordinates for the same X coordinate? Which one will the function return? You wouldn't make a curve like this in the first place, but some people will probably try and they won't get the result they expect.

I guess it's possible to detect when there will be three solutions and warn the user or something.

Anyway thanks for looking that up, it's interesting to know how some programs are doing this.

RNavega wrote: Thu Sep 08, 2022 12:18 am This x isn't the same as the t parameter, it's more like a vertical ray crossing the curve.
It's not the same as the t parameter in a Bézier curve, but it's the same as the t parameter in a conventional easing formula.
dusoft
Party member
Posts: 238
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: Tiled world with smooth movement transitions

A bit too late, but I recommend using Hump:
RNavega
Party member
Posts: 103
Joined: Sun Aug 16, 2020 1:28 pm

Re: Tiled world with smooth movement transitions

@pgimeno I ported a cubic Bézier sampling code for use with easing, as this is relevant to my interests. I think it's too slow for use with many many objects, as even with the faster branch it still needs two function calls (math.pow and math.sqrt).

In here: viewtopic.php?f=5&t=93791
pgimeno
Party member
Posts: 3227
Joined: Sun Oct 18, 2015 2:58 pm

Re: Tiled world with smooth movement transitions

Nice work. I still don't see Bézier as a good option for this purpose but that's me I guess
darkfrei
Party member
Posts: 735
Joined: Sat Feb 08, 2020 11:09 pm

Re: Tiled world with smooth movement transitions

Actually it must be just a 1D Bezier Curve which is as easy as

Code: Select all

--Quadratic Bezier curve:
y = A*(1-x)^2 + 2*B*(1-x)*x + C*x^2
and

Code: Select all

--Cubic Bezier curve:
y = A*(1-x)^3 + 3*B*(1-x)^2*x + 3*C*(1-x)*x^2 + D*x^3

Who is online

Users browsing this forum: No registered users and 5 guests