Page 1 of 1

EASING functions for moving Objects

Posted: Mon Sep 28, 2009 2:00 am
by eddy
Here is some easing functions.
It can be used to code motions or effects.
(Need 4.4x)

Code: Select all

Enumeration ;list of EASING types 
   #EASE_Linear=0
   #EASE_Min_In
   #EASE_Min_Out
   #EASE_Min_InOut
   #EASE_Light_In
   #EASE_Light_Out
   #EASE_Light_InOut
   #EASE_Medium_In
   #EASE_Medium_Out
   #EASE_Medium_InOut
   #EASE_Heavy_In
   #EASE_Heavy_Out
   #EASE_Heavy_InOut
   #EASE_Max_In
   #EASE_Max_Out
   #EASE_Max_InOut
   
   #EASE_Sine_In
   #EASE_Sine_Out
   #EASE_Sine_InOut
   #EASE_Circular_In
   #EASE_Circular_Out
   #EASE_Circular_InOut
   #EASE_Back_In
   #EASE_Back_Out
   #EASE_Back_InOut
   #EASE_Bounce_In
   #EASE_Bounce_Out
   #EASE_Bounce_InOut
   #EASE_Elastic_In
   #EASE_Elastic_Out
   #EASE_Elastic_InOut
   #EASE_last
EndEnumeration

#MAX_EASING=$10000
Global Dim EASING.f(#EASE_last-1, #MAX_EASING)
Procedure InitEase()
   Protected.i i, b=0, c=1, d=#MAX_EASING, in=0, out=0, ease
   Protected.f s=1.70158, s1=s*1.525
   Protected.f p=d*0.3, p1=p*1.5
   
   For i=0 To d
      Protected t.f=i/d
      Protected k.f=t*2
      If k<1 : in=1 : out=0 : Else : in=0 : out=1 : EndIf
      
      EASING(#EASE_Linear, i)=t
      
      Protected t1.f=t-1
      Protected k1.f=k-1
      Protected k2.f=k-2
      EASING(#EASE_Min_In, i)=c*t*t+b
      EASING(#EASE_Min_Out, i)=-c*t*(t-2)+b
      If in : EASING(#EASE_Min_InOut, i)=(c/2*k*k+b) : EndIf
      If out : EASING(#EASE_Min_InOut, i)=(-c/2*(k1*(k1-2)-1)+b) : EndIf
      
      EASING(#EASE_Light_In, i)=c*t*t*t+b
      EASING(#EASE_Light_Out, i)=c*(t1*t1*t1+1)+b
      If in : EASING(#EASE_Light_InOut, i)=(c/2*k*k*k+b) : EndIf
      If out : EASING(#EASE_Light_InOut, i)=(c/2*(k2*k2*k2+2)+b) : EndIf
      
      EASING(#EASE_Medium_In, i)=c*t*t*t*t+b
      EASING(#EASE_Medium_Out, i)=-c*(t1*t1*t1*t1-1)+b
      If in : EASING(#EASE_Medium_InOut, i)=(c/2*k*k*k*k+b) : EndIf
      If out : EASING(#EASE_Medium_InOut, i)=(-c/2*(k2*k2*k2*k2-2)+b) : EndIf
      
      EASING(#EASE_Heavy_In, i)=c*t*t*t*t*t+b
      EASING(#EASE_Heavy_Out, i)=c*(t1*t1*t1*t1*t1+1)+b
      If in : EASING(#EASE_Heavy_InOut, i)=(c/2*k*k*k*k*k+b) : EndIf
      If out : EASING(#EASE_Heavy_InOut, i)=(c/2*(k2*k2*k2*k2*k2+2)+b) : EndIf
      
      EASING(#EASE_Max_In, i)=c*Pow(2, 10*(t1))+b : If i=0 : EASING(#EASE_Max_In, i)=b : EndIf
      EASING(#EASE_Max_Out, i)=c*(-Pow(2, -10*t)+1)+b : If i=d : EASING(#EASE_Max_Out, i)=b+c : EndIf
      If in : EASING(#EASE_Max_InOut, i)=(c/2*Pow(2, 10*k1)+b) : EndIf
      If out : EASING(#EASE_Max_InOut, i)=(c/2*(-Pow(2, -10*k1)+2)+b) : EndIf
      
      EASING(#EASE_Sine_In, i)=-c*Cos(t*(#PI/2))+c+b
      EASING(#EASE_Sine_Out, i)=c*Sin(t*(#PI/2))+b
      EASING(#EASE_Sine_InOut, i)=-c/2*(Cos(#PI*t)-1)+b
      
      EASING(#EASE_Circular_In, i)=-c*(Sqr(1-t*t)-1)+b
      EASING(#EASE_Circular_Out, i)=c*Sqr(1-t1*t1)+b
      If in : EASING(#EASE_Circular_InOut, i)=(-c/2*(Sqr(1-k*k)-1)+b) : EndIf
      If out : EASING(#EASE_Circular_InOut, i)=(c/2*(Sqr(1-k2*k2)+1)+b) : EndIf
      
      EASING(#EASE_Back_In, i)=c*t*t*((s+1)*t-s)+b
      EASING(#EASE_Back_Out, i)=c*(t1*t1*((s+1)*t1+s)+1)+b
      If in : EASING(#EASE_Back_InOut, i)=(c/2*(k*k*((s1+1)*k-s1))+b) : EndIf
      If out : EASING(#EASE_Back_InOut, i)=(c/2*(k2*k2*((s1+1)*k2+s1)+2)+b) : EndIf
      
      If (t=0)
         EASING(#EASE_Elastic_In, i)=b
         EASING(#EASE_Elastic_Out, i)=b
         EASING(#EASE_Elastic_InOut, i)=b
      ElseIf (t=1)
         EASING(#EASE_Elastic_In, i)=b+c
         EASING(#EASE_Elastic_Out, i)=b+c
         EASING(#EASE_Elastic_InOut, i)=b+c
      Else
         Protected.f a, se, se1
         If (a=0 Or a<Abs(c))
            a=c
            se=p/4
            se1=p1/4
         Else
            se=p/(2*#PI)*ASin(c/a)
            se1=p1/(2*#PI)*ASin(c/a)
         EndIf
         EASING(#EASE_Elastic_In, i)=-(a*Pow(2, 10*t1)*Sin((t1*d-se)*(2*#PI)/p))+b
         EASING(#EASE_Elastic_Out, i)=(a*Pow(2, -10*t)*Sin((t*d-se)*(2*#PI)/p)+c+b)
         If in : EASING(#EASE_Elastic_InOut, i)=(-0.5*(a*Pow(2, 10*(k1))*Sin((k1*d-se1)*(2*#PI)/p1))+b) : EndIf
         If out : EASING(#EASE_Elastic_InOut, i)=(a*Pow(2, -10*(k1))*Sin((k1*d-se1)*(2*#PI)/p1)*0.5+c+b) : EndIf
      EndIf
      
      If (t<(1/2.75))
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t)+b
      ElseIf (t<(2/2.75))
         t-(1.5/2.75)
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t+0.75)+b
      ElseIf (t<(2.5/2.75))
         t-(2.25/2.75)
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t+0.9375)+b
      Else
         t-(2.625/2.75)
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t+0.984375)+b
      EndIf
      EASING(#EASE_Bounce_In, d-i)=c-EASING(#EASE_Bounce_Out, i)+2*b
   Next
   For i=0 To d
      t.f=i/d
      k.f=t*2
      If k<1 : in=1 : out=0 : Else : in=0 : out=1 : EndIf
      
      If in : EASING(#EASE_Bounce_InOut, i)=EASING(#EASE_Bounce_In, i*2)*0.5+b : EndIf
      If out : EASING(#EASE_Bounce_InOut, i)=EASING(#EASE_Bounce_Out, i*2-d)*0.5+c*0.5+b : EndIf
   Next
   
EndProcedure
Procedure.f EasingTime(time, duration, easing)
   Protected i=#MAX_EASING*time/duration
   If i<0 Or i>#MAX_EASING
      ProcedureReturn #False
   Else
      ProcedureReturn EASING(easing, i)
   EndIf
EndProcedure
Procedure.f EasingPercent(percent, easing)
   Protected i=#MAX_EASING*percent/100.0
   If i<0 Or i>#MAX_EASING
      ProcedureReturn #False
   Else
      ProcedureReturn EASING(easing, i)
   EndIf
EndProcedure
InitEase()

; ********************
; TEST
; ********************

Procedure.i PositionCalculation(TimeInSecond, DurationInSecond, Start, Distance)
   Protected Position=Start+Distance*EasingTime(TimeInSecond, DurationInSecond, #EASE_Light_In)
   ProcedureReturn Position
EndProcedure

Procedure.i PositionCalculation2(ProgressInPercent, Start, Distance)
   Protected Position=Start+Distance*EasingPercent(ProgressInPercent, #EASE_Light_In)
   ProcedureReturn Position
EndProcedure

Debug PositionCalculation(20, 60, 10, 1000) ;// 20s ellapsed
Debug PositionCalculation2(40, 10, 1000) ;// 40% 

Re: EASING functions

Posted: Mon Sep 28, 2009 2:05 am
by eddy
Easing effects on motion :mrgreen:

Image

Re: EASING functions

Posted: Mon Sep 28, 2009 10:38 am
by Fluid Byte
---------------------------
PureBasic
---------------------------
Line 40: Syntax error.
---------------------------
OK
---------------------------

Re: EASING functions

Posted: Mon Sep 28, 2009 10:56 am
by Kaeru Gaman
@eddy
give your code a Header wich states the Version it runs with.
if you publish code that runs with a beta but not with the stable you name in your signature, you should at least tell the folks.

Additionally, some Documentation how to use this code and what to do with it would be nice ... no, even necessary!
debugging two values is no description.
It may be some great functionallity, but atm you don't see nothing, it's just disappointing to run it.
the screenshot is the only thing that gives a slight idea what it is all about.
to most people "easing" is what they do on the toilet, so you should give a whole bunch of information what this is all about.

Re: EASING functions for moving Objects

Posted: Mon Sep 28, 2009 3:51 pm
by Seymour Clufley
Eddy,

First, thank you for all the fine code you post on this forum.

However, the code isn't much good without a demo program. The screenshot looks amazing, but I need to know how to use the code to make an image like that!

Thank you,
Seymour.

Re: EASING functions for moving Objects

Posted: Mon Sep 28, 2009 9:16 pm
by Rook Zimbabwe
I redid it to werk with PB4.3

Code: Select all


Procedure InitEase()
   Protected i, b=0, c=1, d=#MAX_EASING, INp=0, OUTp=0, ease
   Protected s=1.70158, s1=s*1.525
   Protected p=d*0.3, p1=p*1.5
   
   For i=0 To d
      Protected t.f=i/d
      Protected k.f=t*2
      If k<1 : INp=1 : OUTp=0 : Else : INp=0 : OUTp=1 : EndIf
      
      EASING(#EASE_Linear, i)=t
      
      Protected t1.f=t-1
      Protected k1.f=k-1
      Protected k2.f=k-2
      EASING(#EASE_Min_In, i)=c*t*t+b
      EASING(#EASE_Min_Out, i)=-c*t*(t-2)+b
      If INp : EASING(#EASE_Min_InOut, i)=(c/2*k*k+b) : EndIf
      If OUTp : EASING(#EASE_Min_InOut, i)=(-c/2*(k1*(k1-2)-1)+b) : EndIf
      
      EASING(#EASE_Light_In, i)=c*t*t*t+b
      EASING(#EASE_Light_Out, i)=c*(t1*t1*t1+1)+b
      If INp : EASING(#EASE_Light_InOut, i)=(c/2*k*k*k+b) : EndIf
      If OUTp : EASING(#EASE_Light_InOut, i)=(c/2*(k2*k2*k2+2)+b) : EndIf
      
      EASING(#EASE_Medium_In, i)=c*t*t*t*t+b
      EASING(#EASE_Medium_Out, i)=-c*(t1*t1*t1*t1-1)+b
      If INp : EASING(#EASE_Medium_InOut, i)=(c/2*k*k*k*k+b) : EndIf
      If OUTp : EASING(#EASE_Medium_InOut, i)=(-c/2*(k2*k2*k2*k2-2)+b) : EndIf
      
      EASING(#EASE_Heavy_In, i)=c*t*t*t*t*t+b
      EASING(#EASE_Heavy_Out, i)=c*(t1*t1*t1*t1*t1+1)+b
      If INp : EASING(#EASE_Heavy_InOut, i)=(c/2*k*k*k*k*k+b) : EndIf
      If OUTp : EASING(#EASE_Heavy_InOut, i)=(c/2*(k2*k2*k2*k2*k2+2)+b) : EndIf
      
      EASING(#EASE_Max_In, i)=c*Pow(2, 10*(t1))+b : If i=0 : EASING(#EASE_Max_In, i)=b : EndIf
      EASING(#EASE_Max_Out, i)=c*(-Pow(2, -10*t)+1)+b : If i=d : EASING(#EASE_Max_Out, i)=b+c : EndIf
      If INp : EASING(#EASE_Max_InOut, i)=(c/2*Pow(2, 10*k1)+b) : EndIf
      If OUTp : EASING(#EASE_Max_InOut, i)=(c/2*(-Pow(2, -10*k1)+2)+b) : EndIf
      
      EASING(#EASE_Sine_In, i)=-c*Cos(t*(#PI/2))+c+b
      EASING(#EASE_Sine_Out, i)=c*Sin(t*(#PI/2))+b
      EASING(#EASE_Sine_InOut, i)=-c/2*(Cos(#PI*t)-1)+b
      
      EASING(#EASE_Circular_In, i)=-c*(Sqr(1-t*t)-1)+b
      EASING(#EASE_Circular_Out, i)=c*Sqr(1-t1*t1)+b
      If INp : EASING(#EASE_Circular_InOut, i)=(-c/2*(Sqr(1-k*k)-1)+b) : EndIf
      If OUTp : EASING(#EASE_Circular_InOut, i)=(c/2*(Sqr(1-k2*k2)+1)+b) : EndIf
      
      EASING(#EASE_Back_In, i)=c*t*t*((s+1)*t-s)+b
      EASING(#EASE_Back_Out, i)=c*(t1*t1*((s+1)*t1+s)+1)+b
      If INp : EASING(#EASE_Back_InOut, i)=(c/2*(k*k*((s1+1)*k-s1))+b) : EndIf
      If OUTp : EASING(#EASE_Back_InOut, i)=(c/2*(k2*k2*((s1+1)*k2+s1)+2)+b) : EndIf
      
      If (t=0)
         EASING(#EASE_Elastic_In, i)=b
         EASING(#EASE_Elastic_Out, i)=b
         EASING(#EASE_Elastic_InOut, i)=b
      ElseIf (t=1)
         EASING(#EASE_Elastic_In, i)=b+c
         EASING(#EASE_Elastic_Out, i)=b+c
         EASING(#EASE_Elastic_InOut, i)=b+c
      Else
         Protected a, se, se1
         If (a=0 Or a<Abs(c))
            a=c
            se=p/4
            se1=p1/4
         Else
            se=p/(2*#PI)*ASin(c/a)
            se1=p1/(2*#PI)*ASin(c/a)
         EndIf
         EASING(#EASE_Elastic_In, i)=-(a*Pow(2, 10*t1)*Sin((t1*d-se)*(2*#PI)/p))+b
         EASING(#EASE_Elastic_Out, i)=(a*Pow(2, -10*t)*Sin((t*d-se)*(2*#PI)/p)+c+b)
         If INp : EASING(#EASE_Elastic_InOut, i)=(-0.5*(a*Pow(2, 10*(k1))*Sin((k1*d-se1)*(2*#PI)/p1))+b) : EndIf
         If OUTp : EASING(#EASE_Elastic_InOut, i)=(a*Pow(2, -10*(k1))*Sin((k1*d-se1)*(2*#PI)/p1)*0.5+c+b) : EndIf
      EndIf
      
      If (t<(1/2.75))
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t)+b
      ElseIf (t<(2/2.75))
         t-(1.5/2.75)
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t+0.75)+b
      ElseIf (t<(2.5/2.75))
         t-(2.25/2.75)
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t+0.9375)+b
      Else
         t-(2.625/2.75)
         EASING(#EASE_Bounce_Out, i)=c*(7.5625*t*t+0.984375)+b
      EndIf
      EASING(#EASE_Bounce_In, d-i)=c-EASING(#EASE_Bounce_Out, i)+2*b
   Next
   For i=0 To d
      t.f=i/d
      k.f=t*2
      If k<1 : INp=1 : OUTp=0 : Else : INp=0 : OUTp=1 : EndIf
      
      If INp : EASING(#EASE_Bounce_InOut, i)=EASING(#EASE_Bounce_In, i*2)*0.5+b : EndIf
      If OUTp : EASING(#EASE_Bounce_InOut, i)=EASING(#EASE_Bounce_Out, i*2-d)*0.5+c*0.5+b : EndIf
   Next
   
EndProcedure
Replace theis procedure... It gives me two values in the debugger is all... console only gives me nada.

Does need to draw or plot something on a window though...

Re: EASING functions for moving Objects

Posted: Tue Sep 29, 2009 12:52 am
by eddy
It's just an extract from my sprite lib : http://www.purebasic.fr/english/viewtop ... 12&t=38447

If you need more infos, there's a thread about this functionality : http://www.purebasic.fr/english/viewtop ... 16&t=39259
I took time to convert the actionscript to PB.
Sorry but I can't convert the whole project. :|

If you have time to code a simple example, you can post here.

Re: EASING functions for moving Objects

Posted: Mon Oct 12, 2009 5:35 pm
by thyphoon
Excellent !

Can you add juste a little exemple with a Sprite to understand how to use it ?

Very good job thanks to share with us !

Re: EASING functions for moving Objects

Posted: Wed Feb 03, 2010 10:52 pm
by aonyn
Very Nice!

I was just browsing back a way in the Tips forum, and stumbled on this.
Very useful, and seems to work well, I have been playing with it for the past hour.

Thanks for sharing Eddy.

regards,
Dave