Inverted Smoothstep?

5.7k Views Asked by At

I am currently trying to simulate ballistics on an object, that is otherwise not affected by physics. To be precise, I have a rocket-like projectile, that is following an parabolic arc from origin to target with a Lerp. To make it more realistic, I want it not to move at constant speed, but to slow down towards the climax and speed up on its way back down.

I have used the Mathf.Smoothstep function to do the exact opposite of what i need on other objects, i.e. easing in and out of the motion.

So my question is: How do I get an inverted Smoothstep?

I found out that what i would need is actually the inverted formula to smoothstep [ x * x*(3 - 2*x) ], but being not exactly a math genius, I have no idea how to do that. All I got from online calculators was some pretty massive new function, which I'm afraid would not be very efficient.

So maybe there is a function that comes close to an inverted smoothstep, but isn't as complex to compute.

Any help on this would be much appreciated

Thanks in advance,

Tux

4

There are 4 best solutions below

9
jbernardo On

You seem to want a regular parabola. See the graph of this function:

http://www.wolframalpha.com/input/?i=-%28x%2A2-1%29%5E2%2B1

Which is the graph that seems to do what you want: -(x*2-1)^2+1

It goes from y=0 to y=1 and then back again between x=0 and x=1, staying a bit at the top around x=0.5 . It's what you want, if I understood it correctly.

Other ways to write this function, according to wolfram alpha, would be -(4*(x-1)*x) and (4-4*x)*x

Hope it helps.

0
Max Yankov On

If you're moving transforms, it is often a good idea to user iTween or similar animation libraries instead of controlling animation yourself. They have a an easy API and you can set up easing mode too.

But if you need this as a math function, you can use something like this:

y = 0.5 + (x > 0.5 ? 1 : -1) * Mathf.Pow(Mathf.Abs(2x - 1),p)/2

Where p is the measure of steepness that you want. Here's how it looks:

graph

1
FeatureCreep On

I had a similar problem. For me, mirroring the curve in y = x worked:

enter image description here

So an implementation example would be:

float Smooth(float x) {
    return x + (x - (x * x * (3.0f - 2.0f * x)));
}

This function has no clamping, so that may have to be added if x can go outside the 0 to 1 interval.

Wolfram Alpha example

0
Esenthel On

Correct formula is available here: https://www.shadertoy.com/view/MsSBRh

Solution by Inigo Quilez and TinyTexel

Flt SmoothCubeInv(Flt y)
{
   if(y<=0)return 0;
   if(y>=1)return 1;
   return 0.5f-Sin(asinf(1-2*y)/3);
}