Make Your Own Interpolations
RThurman
Member, Sous Chef, PRO Posts: 2,880
Hey this is my 1000th posting in the GameSalad Forums!
To celebrate, I thought I'd share how interpolations work and how you can 'roll your own' so you don't need to be dependent on the GS implementation.
Why would you want to create your own custom interpolation behavior? Among other things it means you could create interpolations that:
1) don't have 'the glitch'.
2) don't override/interfere with collisions.
3) can stop any time you want.
So what is an interpolation? Its simply a mathematical way of filling in the blanks between two numbers. For example, to fill in the missing numbers in this sequence, you need to interpolate:
1,_,_,_,_,_,_,_,_,10
(As an aside, to extrapolate means to continue the number sequence beyond whats given. So extrapolation is continuing the sequence: 2,4,6,8,10,_,_,_,_,_,_)
The general formula for interpolation looks like this:
c*(t/d)+b
c = the total change (from beginning to end) of some value (like position, or rotation, or alpha, or volume).
t = the current time
d = the duration of the interpolation
b = the beginning value of something (like position, or rotation, or alpha, or volume)
So, lets say you have an actor that is at self.position.X = 50 and you want it move 75 pixels to the right. And you want to move those 75 pixels in 5 seconds.
self.b = 50
self.c = 50+75 = 125
self.t = self.Time - self.BeginTime
self.d = 5
Here would be a quick example of an interpolation loop:
for d seconds
--Constrain Attribute: self.t To: self.Time - self.BeginTime
--Constrain Attribute: self.Position.X To: self.c*(self.t/self.d)+ self.b
The above example would be for a linear interpolation.
GameSalad also has an "ease in" interpolation. It does this with a power function. The raw equation looks something like:
c*((t/d)*(t/d))+b
That is, the t/d part is squared (or raised to the power of 2).
The GameSalad implementation would look something like this:
--Constrain Attribute: self.Position.X To: self.c*pow((self.t/self.d),2)+ self.b
or
--Constrain Attribute: self.Position.X To: self.c*((self.t/self.d)^2)+ self.b
GameSalad also has an "ease out" interpolation. Its equation looks like this:
c*(1-((1-t/d)*(1-t/d))+b
The GameSalad implementation would look something like this:
--Constrain Attribute: self.Position.X To: self.c*(1-pow(1-(self.t/self.d),2))+ self.b
or
--Constrain Attribute: self.Position.X To: self.c*(1-(1-self.t/self.d)^2)+ self.b
You can go beyond GameSalad's standard ease in / ease out by by modifying the 't/d' part. For example, the GameSalad version uses (t/d)^2 (called the quadratic form). But you could also use (t/d)^3 (called the cubic form). Or you could use any power function -- like (t/d)^5 (which is called the quintic form).
You could also use use 'sin' and 'cos' to modify the (t/d) part and get whats called a sinusoidal interpolation. In fact, @socks famous "AAA*sin(self.Time*BBB)+CCC" is an equation for linear sinusoidal interpolation.
AAA corresponds 'd'
CCC corresponds 'b'
self.Time corresponds to (t/d)
BBB is some multiplier (sort of like the power functions above)
You could modify @socks' equation to do an ease in. It would look like this:
Constrain Attribute: Self.Position.X To: self.c*(1-cos(self.t/self.d*(3.1415/2)))+ self.b
Ease out would be:
Constrain Attribute: Self.Position.X To: self.c*(sin(self.t/self.d*(3.1415/2)))+ self.b
(Note: 3.1415/2 is the calculation for pi/2)
-----------------------
Attached is a demo project that has several of the easing functions discussed above. Take a look at it and study how it works. Then you can create your own interpolations!
http://www.mediafire.com/download.php?b9se71y0jtpp3wy
To celebrate, I thought I'd share how interpolations work and how you can 'roll your own' so you don't need to be dependent on the GS implementation.
Why would you want to create your own custom interpolation behavior? Among other things it means you could create interpolations that:
1) don't have 'the glitch'.
2) don't override/interfere with collisions.
3) can stop any time you want.
So what is an interpolation? Its simply a mathematical way of filling in the blanks between two numbers. For example, to fill in the missing numbers in this sequence, you need to interpolate:
1,_,_,_,_,_,_,_,_,10
(As an aside, to extrapolate means to continue the number sequence beyond whats given. So extrapolation is continuing the sequence: 2,4,6,8,10,_,_,_,_,_,_)
The general formula for interpolation looks like this:
c*(t/d)+b
c = the total change (from beginning to end) of some value (like position, or rotation, or alpha, or volume).
t = the current time
d = the duration of the interpolation
b = the beginning value of something (like position, or rotation, or alpha, or volume)
So, lets say you have an actor that is at self.position.X = 50 and you want it move 75 pixels to the right. And you want to move those 75 pixels in 5 seconds.
self.b = 50
self.c = 50+75 = 125
self.t = self.Time - self.BeginTime
self.d = 5
Here would be a quick example of an interpolation loop:
for d seconds
--Constrain Attribute: self.t To: self.Time - self.BeginTime
--Constrain Attribute: self.Position.X To: self.c*(self.t/self.d)+ self.b
The above example would be for a linear interpolation.
GameSalad also has an "ease in" interpolation. It does this with a power function. The raw equation looks something like:
c*((t/d)*(t/d))+b
That is, the t/d part is squared (or raised to the power of 2).
The GameSalad implementation would look something like this:
--Constrain Attribute: self.Position.X To: self.c*pow((self.t/self.d),2)+ self.b
or
--Constrain Attribute: self.Position.X To: self.c*((self.t/self.d)^2)+ self.b
GameSalad also has an "ease out" interpolation. Its equation looks like this:
c*(1-((1-t/d)*(1-t/d))+b
The GameSalad implementation would look something like this:
--Constrain Attribute: self.Position.X To: self.c*(1-pow(1-(self.t/self.d),2))+ self.b
or
--Constrain Attribute: self.Position.X To: self.c*(1-(1-self.t/self.d)^2)+ self.b
You can go beyond GameSalad's standard ease in / ease out by by modifying the 't/d' part. For example, the GameSalad version uses (t/d)^2 (called the quadratic form). But you could also use (t/d)^3 (called the cubic form). Or you could use any power function -- like (t/d)^5 (which is called the quintic form).
You could also use use 'sin' and 'cos' to modify the (t/d) part and get whats called a sinusoidal interpolation. In fact, @socks famous "AAA*sin(self.Time*BBB)+CCC" is an equation for linear sinusoidal interpolation.
AAA corresponds 'd'
CCC corresponds 'b'
self.Time corresponds to (t/d)
BBB is some multiplier (sort of like the power functions above)
You could modify @socks' equation to do an ease in. It would look like this:
Constrain Attribute: Self.Position.X To: self.c*(1-cos(self.t/self.d*(3.1415/2)))+ self.b
Ease out would be:
Constrain Attribute: Self.Position.X To: self.c*(sin(self.t/self.d*(3.1415/2)))+ self.b
(Note: 3.1415/2 is the calculation for pi/2)
-----------------------
Attached is a demo project that has several of the easing functions discussed above. Take a look at it and study how it works. Then you can create your own interpolations!
http://www.mediafire.com/download.php?b9se71y0jtpp3wy
Comments
Brilliant stuff !!!!
(even though I don't understand any of it !! ) ).
+ Happy 1000th, you don't look older than 980.
It'd be awesome if we could do a *move to location and slightly overshoot it, and then zoom back* function. Or just customize the easing on both sides.
I think that's what you're trying to get cross that we can do. Thanks for the post!
- Thomas
P.S. Happy 100th
My GameSalad Academy Courses! ◦ Check out my quality templates! ◦ Add me on Skype: braydon_sfx
EDIT: Whoah, opening the project just about made my dizzy... may have to wait to digest this...
@socks -- I am anxious to see if some of this is useful for you. (You know, what with that awful glitch you seem to have caught )
@SnapFireStudios -- yes you can create an overshoot and bounce back function. If interested I can send it to you in a PM. I'm afraid the equation will look unintelligible. But it does work.
@Braydon_SFX -- thanks man. I guess this posting counts as 1001.
@JarrenH -- yes they are totally interrupt-able. It might look a little over-the-top but most of the behaviors are just setting stuff up. Plus there are three sets of behaviors in most actors (EaseIn, EaseOut, and EaseInOut). That makes it look like there is much more there (than there really is).
@beefy_clyro -- TMI??
@ericzingeler -- Thanks! I hope its useful.
- Thomas
The only thing I want to know is that if the last 10% of the last whole number in the interpolate algorithm is missing then who is taking it ? Someone is obviously siphoning off that tiny fraction from everyone else's interpolate behaviours and keeping those numbers for themselves, sure it's not a lot by itself, but repeated millions of times we are looking at a fairly substantial amount.
This would be really useful (could I see it too ?), especially if the overshoot went passed the target destination by a certain amount - then bounced back to overshoot in the other direction by a little less, then back the other way even less again (and so on) so you end up with a nice bouncy elastic wobble - or is that kind of thing a bit too much to ask of a single piece of maths ?
Anyway, I love to see the overshoot + bounce back !
Chees for sharing all this stuff !
>-
I put it into the format you are familiar with. It is a version of AAA*sin(self.Time*BBB)+CCC
It even has a function generator so you can make your own easing... erm, easy
Adobe Edge Animate uses this 'engine'.
Lump Apps and My Assets
Website » Twitter » Facebook » Loaded Arts - Fun for thumbs.
Developer Blog » 08/01/2015 - Week 72 – Apple, the great dictator…
But when the asteroids stop I cant get them to recycle, also I cant seem to define the beginning X / Y as the white actors location. I have 10 asteroids recycling.
Maybe I need to re-read you method again and tinker with my logic.
Website » Twitter » Facebook » Loaded Arts - Fun for thumbs.
Developer Blog » 08/01/2015 - Week 72 – Apple, the great dictator…
@RThurman
Don't know how I missed this before... awesome it is though... Excellent stuff, RT! :-)
""You are in a maze of twisty passages, all alike." - Zork temp domain http://spidergriffin.wix.com/alphaghostapps
@gyroscope -- Thanks! GameSalad is great for exploring this kind of stuff.
There might be an easier way that will save a ton of processing. Could you simply have the asteroids change size as they get further away from the emitter. Something like this:
Constrain Attribute: self.size.height To: magnitude (self.Position.X - emitter.Position.X, self.Position.Y - emitter.Position.Y)
Constrain Attribute: self.Size.width To: self.size.height
There are many ways to skin a rabbit
Website » Twitter » Facebook » Loaded Arts - Fun for thumbs.
Developer Blog » 08/01/2015 - Week 72 – Apple, the great dictator…
Thanks in advance, I appreciate any help
Website » Twitter » Facebook » Loaded Arts - Fun for thumbs.
Developer Blog » 08/01/2015 - Week 72 – Apple, the great dictator…
Website » Twitter » Facebook » Loaded Arts - Fun for thumbs.
Developer Blog » 08/01/2015 - Week 72 – Apple, the great dictator…
Think of all the millions of GameSalad users who will search on the forums for a question just like yours. But because its buried in an unrelated discussion, it will never be found.
How about starting a new thread and title it something like, "How to make actors grow and shrink according to distance from some arbitrary point." (Hmmm.... thats too long. You better think of a shorter title!)
Website » Twitter » Facebook » Loaded Arts - Fun for thumbs.
Developer Blog » 08/01/2015 - Week 72 – Apple, the great dictator…
One quick thing though. I'm not sure how much this will affect accuracy, but pi equals about 3.14159265 which would round more closely to 3.1416.