Exponential increase/decrease using time_step...

Posted By: Chaeon

Exponential increase/decrease using time_step... - 12/12/08 23:34

im trying to achieve camera movement that deceases in speed the closer the camera gets to its optimum position, above the player model. the obvious way to go about this is by subtracting a percentage of the remaining distance to cover from the camera's position:

camera.x -= .02 * (camera.x - intended.x);
camera.y -= .02 * (camera.y - intended.y);

this is nice and smooth, but the camera would move around faster on faster hardware, and just multiplying the percentage by time_step doesn't work because the problem deals with exponents(and subtracting a percentage twice as big with half the frequency yeilds different results). Any ideas on how to factor time_step into an exponential increase or decrease?
thanks people!

btw this problem pops up in several places in my project, the camera scenario's just the easiest way to explain it.
Posted By: EvilSOB

Re: Exponential increase/decrease of a value... - 12/13/08 08:30

camera.x -= .02 * (intended.x - camera.x) * time_step;
camera.y -= .02 * (intended.y - camera.y) * time_step;

You may need to increase the 0.02 to get the old feel(probably about 0.1), but
it will now be stable across all hardware speeds, once you found that number for yours.
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/13/08 23:02

Thanks for your reply evilSOB

But the point of the question is that just poking time_step in DOESN'T work, because subtracting a percentage of a number once a second (for example) produces a faster decrease than subtracting a quarter of that percentage four times a second, right? So normal time_step doesn't work.

I think the answer would have something to do with multiplying a power by time_step, but i don't know how it would work. I'll keep thinking but any suggestions are appreciated.
Posted By: ventilator

Re: Exponential increase/decrease of a value... - 12/14/08 00:03

Quote:
because subtracting a percentage of a number once a second (for example) produces a faster decrease than subtracting a quarter of that percentage four times a second, right?
no, why do you think so? simply multiplying time_step works fine.
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/14/08 01:16

Because:

(assume target camera x position is 0, and assume camera.x is twenty)

faster machine: time_step = 4:

camera.x -= .02 * (camera.x - 0) * 4;

wait(1); // camera.x now equals 18.4

camera.x -= .02 * (camera.x - 0) * 4;

wait(1); // camera.x now equals 16.928

camera.x -= .02 * (camera.x - 0) * 4;

wait(1); // camera.x now equals 15.57376

camera.x -= .02 * (camera.x - 0) * 4;

wait(1); // an amount of time has passed. camera.x now equals 14.3278592

final camera.x after one second on faster machine is 14.3278592



slower machine: time_step = 2:

camera.x -= .02 * (camera.x - 0) * 2;

wait(1); // camera.x now equals 19.2

camera.x -= .02 * (camera.x - 0) * 2;

wait(1); // same amount of time has passed. camera.x now equals 18.432

final camera.x after one second on slower machine is 18.432

hence decrease of camera.x is greater on faster computers if you use

camera.x -= .02 * (camera.x - 0) * time_step;


well i was wrong when i said that a faster machine would produce slower camera movement (mostly due to the painfully noobish assumption that time_step reflects the number of frames that occurred in the last second), but the point remains the same. Because i'm dealing with exponents the usual means of implementing time_step doesn't work. I've really got some thinking to do. Perhaps i should start a new thread, as ive made such a mess of this one? Nah ill just correct the first post
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/14/08 01:43

camera.x += (target.x - camera.x) * pow(reductionpersecond,16/time_step)

target.x is the target camera position (0 in your example).
reductionpersecond is the percentage of the distance that should be covered each second.
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/14/08 02:56

great!!! i knew there must be something! thanks so much bigM you are a genius. ill try it out now, it looks correct...
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/14/08 05:12

one question though, out of curiosity..

where does the 16 come from? i thought a tick was a sixteenth of a second, but this formula has nothing to do with ticks, or does it?
Posted By: testDummy

Re: Exponential increase/decrease of a value... - 12/14/08 05:39

It seems ventilator is correct, with precision being a consideration.

Try reversing 2 and 4 (above in example calcs).


Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/14/08 09:11

nooo! bigM's formula doesn't seem to work, and I have no idea how to adjust it because i don't know how it works because it has that mysterious 16 in it!
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/14/08 10:19

So,
from the manual, time_step is the smoothed version of time_frame, which is "The duration of the last frame cycle in ticks, i.e. sixteenths of a second". If you want to work with seconds you must always divide time_step (or time_frame) by 16.

I have not tried the equation myself but it should work. I noticed a bug in what I wrote: reductionpersecond is not a percentage, but a value between 0 and 1, maybe that's why it didn't work out for you.

One other thing I don't get from your example is the higher time_step for a faster computer: a large time_step means a larger lag between frames, which translates to a lower framerate. Slow computers have lower framerates, fast ones have higher rates.

Ask if you want me to explain the equation more in detail.
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/14/08 10:28

Damn, a stupid mistake:

it should be

camera.x += (target.x - camera.x) * pow(reductionpersecond,time_step/16)

(with reductionpersecond between 0 and 1)

Now it should work.
pow(reductionpersecond,time_step/16) is the corrected reduction factor; if a frame lasts 0.5 secs the factor will be the square root of reductionpersecond, a second frame of 0.5 secs will have another decrease by the same factor, which means that after two frames (1 second) there will be a total reduction of factor1*factor2 which equals reductionpersecond.

Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/14/08 10:32

By the way, after you get it working, maybe it's best to work with time_frame instead of time step because that will give you the exact elapsed time from the previous frame, not a smoothed time. I think it may prevent some jitter if the fremerate suddenly changes.

Anyway, this is just dry talk. Like the equation, I did not test it.

Let me know how it works for you.
Posted By: ventilator

Re: Exponential increase/decrease of a value... - 12/14/08 12:53

hm... i never had problems with simply multiplying the time_step. you will reach the target in the same time. of course there will be inaccuracies and the curve will look a bit differently but this never was noticeable as a problem to me. you should also make sure that the time_step never causes the factor to be 0 or bigger than 1.

it would be interesting to have some comparison tables or curves of both methods. at a first glance i can't really imagine what the pow solution does. it seems to be wrong to me. smile

edit:

simply multiplying time_step:

i don't see any problem here? you could say "hey, the error is 200% after the time span" but both are very near to the target already and the difference shouldn't be noticable by anyone.



if i understand it correctly the pow method takes less steps with a higher framerate. it won't work at all.
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/15/08 04:36

Sorry, only got to reply now:

There was yet another small mistake in my equation, final version now:
camera.x += (target.x - camera.x) * pow(1 - reductionpersecond,time_step/16)

I simulated three different timesteps with both methods. Mine gives the exact same results for all timesteps, but I guess it may be slower because of the use of pow. Yours has small precision errors but I'm not sure if they have importance at any scale. I think it will ultimately depend on the situation.



Please let me know what you think.
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/15/08 10:19

haha two titans are slugging in out in my thread!!

after i found that bigM's thingy still didn't work (and now i have to go make the "1-" change) i smacked together a third method, which is hideous to look at, and slow, but seems to do the job:

camera.x = (pow(sqrt(abs(camera.x - target.x)) - (time_step * .5),2) * sign(camera.x - target.x)) + target.x;

(Was missing bracket, fixed now)

just thought i'd post it for the sake. its based on the parabola y = x^2, where x represents time and y represents the camera's position relative to target.x.

so yea. if bigM's works now i'll go with that.

blast of course it doesn't! with or without a "1 -" the camera is stuck at target.x constantly! ahh well at least i have a backup plan frown

i dont get how it's meant to work.. pow(reductionspersecond,16 / time_step) seems to always yeild a number very close to one. so the camera appears stuck over the entity...
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/15/08 13:59

confused
Damn... I'd better try this with real code, rather than just theoretically.

(By the way, how much are you using for reductionpersecond?)

Best luck
Posted By: ventilator

Re: Exponential increase/decrease of a value... - 12/15/08 18:11

why overcomplicate things if the difference is only visible as a small aberration in some excel graphs? nobody will notice this in your game. smile

if your frame rate isn't fixed you will have such small inaccuracies in other areas like physics too. i wouldn't bother about it.
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/15/08 19:16

Yeah, I agree with you ventilator.

I guess that if neither approach is working there is probably some other problem in the code that needs to be solved.

I did spot a problem in Chaeon's implementation: pow(reductionspersecond,16 / time_step) should be
pow(1-reductionspersecond,time_step/16)

(notice the '1-' and the inversion of time_step/16)
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/15/08 23:53

!!? my thingy doesn't have a sixteen or a 1-, its a completely different way of doing it. its converting the curve into a steady decrease, altering it by subtracting time_step * a_number and the converting it back. i think that this is the best way to go about the thing, as steady increases and decreases in values are far easier.

and yes, perhaps slight differences in the camera could go unnoticable, but the camera was only an example i used to demonstrate a problem in far more touchy parts of the code.

hey its off topic, but i wrote a quick function at the top of the script that i've been using in situations like this, and id just like a professional view on it, just to see if im in the right direction in terms of programming's "layers of abstraction", y'know? writing reusable code. is this a common method?

near beginning of script:

function closesttozero(element_a,element_b)
{
if(minv(abs(element_a),abs(element_b)) == abs(element_a))
return(element_a);
else
return(element_b);
}

its handy for things like

speeds -= closesttozero(speeds,20 * time_step * sign(speeds));

would you say my methods were too slow?
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/16/08 11:17

Hi again,
Sorry Chaeon, bad choice of words. What I meant by 'Chaeon's implementation' was your implementation of my equation.

I did not analyze your equation in detail but it does seem to be compatible with the parabola, and if it works, it is far better than any other aproach grin

I can't comment on the rest of your code.
Posted By: Chaeon

Re: Exponential increase/decrease of a value... - 12/16/08 22:35

Alright! ive got all i need then! thanks for playing people, its been interesting. one step closer to completiooon..

bigM fixed the last bug in his power method and it works perfectly: i don't really understand it but that can come a little later.

camera.x += (target.x - camera.x) * (1 - pow(1 - reductionpersecond,time_step/16))

thank you bigM

and i finally thought of an appropriate signature:

"i HEART 3dgs."
Posted By: BigM

Re: Exponential increase/decrease of a value... - 12/17/08 17:08

Glad I could help,

A minor improvement:

camera.x += (target.x - camera.x) * (1 - pow(1 - reductionpertick , time_step))

This is essentially the same equation, but there is no need to divide every frame by 16, which speeds things up a bit. Note that you'll have to use much smaller values for reductionpertick than for reductionpersecond ( reductionpertick = 1 - (1 - reductionpersecond)^(1/16) )

Because this will be calculated every frame another slight improvement may be calculating (1 - reductionpertick) beforehand:

leftdistancepertick = (1 - reductionpertick)

and use that result in the equation:

camera.x += (target.x - camera.x) * (1 - pow(leftdistancepertick , time_step))
© 2024 lite-C Forums