Forum Moderators: open

Message Too Old, No Replies

Sine waves.

Need to calculate stopping distance...

         

Dabrowski

4:12 am on Jan 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ok, I'm writing a little animation, and without me working it out it would be useful to calculate a smooth stopping distance.

I use sine waves a lot to calculate smooth animation, acceleration, deceleration, fading colour etc....

So I have the formula:

(object/coordinate/colour/other) is (travelling/fading) at (x) (pixels/steps) per (some time).

I know what I want the ending (location/speed/colour) to be, but what I need to know, is the time it will take to get there based on a sine wave. Is there a way of calculating it, or should I just stick with the way I am currently doing it - add up all values I get from the sine wave?

phranque

6:35 am on Jan 16, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



a sine wave is cyclic, so i'm not sure i understand your question.

assuming your absolute value is less than the amplitude of the wave, the sine wave will reach your target value twice per cycle, so it necessarily depends on the frequency of the wave.

Dabrowski

2:28 pm on Jan 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Thanks for the reply phranque, I wasn't sure if anyone would take an interest in this one.

Hmmm, ok, lets take an actual reale worlde example.

I have an image. Lets say it's a little arrow or something. Now, when I hover the mouse over something I want the arrow to move at 300px per second.

I would use a sine wave to accelerate it over say 1/2 a second to smooth the motion.

Now, I have a specific point where I want the arrow to stop, I know the total distance it should have travelled, and I want it to take 1/2 a second to slow down and stop.

But how do I know when to begin deceleration? When the sine wave kicks in to start slowing down, how far will it travel before it stops?

Fotiman

4:06 pm on Jan 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



I'm not sure if your question is purely educational (that is, you really want to understand the formula), or if you're simply looking to find a solution that works. If it's the latter, then you might try using the Yahoo UI Library's Animation Utility. It includes "Easing", which allows for more fluid animation. Here's a quick example that does what I think you're trying to do:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset:utf-8">
<title></title>
</head>
<body>
<div id="container">
<input type="button" id="activate" value="Animate">
<div id="test" style="overflow:hidden;height:1em;width:1.5em;background-color:#f00;">--&gt;</div>
</div>
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/animation/animation-min.js"></script>
<script type="text/javascript">
YAHOO.util.Event.on(window, 'load', function() {
var myAnim = new YAHOO.util.Motion('test', {
points : { to : [0, 0] } // I decided to calculate this just before animation
}, 1, YAHOO.util.Easing.easeBoth); // Duration: 1 second, with easing to start and stop
YAHOO.util.Event.on('activate', 'click', function() {
// Calculate the motion
// Get the current X and Y location
var x = YAHOO.util.Dom.getX('test');
var y = YAHOO.util.Dom.getY('test');
// Determine how much to move it. In this example, I'm either moving it
// 300px to the right, or 300px to the left, depending on the current X.
var movepx = (x < 300? 300: -300);
myAnim.attributes.points = {
from : [x, y], to : [x + movepx, y]
};
myAnim.animate();
});
});
</script>
</body>
</html>

Dabrowski

8:04 pm on Jan 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Dude you really do work for them don't you?

In answer to your question, both. I am looking to see how it's done, and the calculation involved, and also a solution that works. If you can answer the first part then I can solve the second part myself.

Show a man how to fish.....

Fotiman

9:24 pm on Jan 16, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Hehe... no, I really don't work for them. It's just that they've already invented the wheel, so I have no need to re-invent it. It's such a powerful library... it can handle just about anything you throw at it. :-)

As far as the inner workings of this particular example, you might be able to look through the YUI code to see how they're doing it.

phranque

1:16 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



i can see how you would take a quarter of a sine wave and use it as a velocity multiplier, but you can make that wave as long or as short as you want.
a 1Hz sine wave (1 cycle/second) will take .25 seconds to go from maxiumum amplitude to zero.

daveVk

3:15 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I have a specific point where I want the arrow to stop, I know the total distance it should have travelled, and I want it to take 1/2 a second to slow down and stop

The average speed while stoping will be pi/4 initial speed ( I think ).

So work out dist at initial speed over 1/2 sec and multiply by pi/4 (0.7853981634)

phranque

5:02 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



doh!(head slap!)
it helps to read the question.

the distance traveled is the area under the velocity curve.
the area under a sine curve with an amplitude of 1.0 for 1/4 cycle (0 to pi/2) is 0.5.
therefore the distance should be 0.5 * (initial velocity) * (time to stop).

daveVk

5:19 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



the area under a sine curve with an amplitude of 1.0 for 1/4 cycle (0 to pi/2) is 0.5.

Surely the area is between that of trianglar wave ( 0.5 ) and that of a square wave ( 1.0 ). Am I missing something?

[edited by: daveVk at 5:22 am (utc) on Jan. 17, 2008]

daveVk

7:09 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Correct value seems to be 2/pi

Tastatura

7:39 am on Jan 17, 2008 (gmt 0)

10+ Year Member



a bit of a general info - if you are already familiar with it sorry for the bloat...maybe it will benefit someone else...there is a formula at the end :)

so if I understand your question correctly, you are interested in 'motion control' where you want to accelerate to certain speed, travel at constant speed for a while, and then decelerate to reach your wanted position (location).

There are few simple and complex ways to do this (and is well understood in some engineering disciplines). Simplest way is to use 'triangle' velocity profile - you linearly accelerate for half a distance and then you start to linearly decelerate until you reach your final position (if you plot velocity on y-axis and distance on the x-axis profile will look look a triangle, hence the name).

Another approach is to use "trapezoidal" (trap) velocity profile - you linearly accelerate for a short distance , continue to move at constant velocity for a while, and then linearly decelerate to final position (velocity profile depicts trapezoid hence the name :) )

You can also use sinusoidal profile...

From what you are describing ("...smoothly accelerate , travel at 300 px/s, smoothly decelerate...") my understanding is that you want "composite" profile. In your case - to use part of the sine curve to describe acceleration and deceleration, with constant velocity in between. However you are asking, for "time to do final smooth deceleration until you reach your final destination" - it's certainly possible to figure that out, but usually velocity profiles are thought of in terms of deceleration before reaching final position (final position value is known...and it seems that in your problem you know where flying arrow needs to stop).
Usually "composite" profiles are stitched together from , say, three different basic profiles, while monitoring acceleration (a), but you seem to want to express in in terms of distance. So you would say something like:
- while x is less then some distance (d) ["needed for smooth travel"]use sine velocity profile
-while x is equal to d but less then d1 ["dist. before smooth deceleration ] velocity is 300px/sec {some constant velocity]
- while x is equal to d1 but less then final distance use sine vel profile

above can be written nicer but I just wanted to show that you will have to use 3 formulas to describe the motion. Definitely possible, but perhaps too complex for the scenario you described - it will take bunch of code to describe motion (or maybe not, if you over simplified your example....). I would suggest to just use sine velocity profile, make sine period really big and use just 1/2 period. While the arrow will always accelerate or decelerate (no constant velocity) but with big enough period user looking at the arrow on the screen will not be able to tell the difference. So here are some formulas - you can use them to derive "composite" profile if you so wish)...

I am assuming that you know your final distance (or how long you want to travel). So here is some math and I'll try to simplify it a bit

sine formula in simplest form is given as:

y = A*(sin angle)
where
y is , in your case, velocity at certain angle (distance) during travel
A is maximum amplitude - in your case it would be either maximum velocity in pixels/sec (or constant velocity for composite profile)

we also know that velocity can be expressed as
v = distance / time

Now each wave has a period, which is time for a wave to complete one full cycle (generally - start at minimum (0) raises to max value goes to minimum vale and comes back to 0 ). Period is expressed in units of time (usually seconds).

Interestingly, you can describe a wave by it's wavelength - which is distance it takes a wave to complete one full cycle (note that it's same full cycle as described for above period - useful huh :) ). Note that wavelength is expressed in units of distance (nanometers, meters, or pixels in your case :) ).

Doing a little math, and rearranging basic sine formula and velocity formula, we come up with equation which can express velocity in terms of distance - that's what notation v(x) means

v(x) = A*sin ((2*pi*x) / wavelength)

Because we want to use only 'top' part of the sine wave, i.e only accelerate and then decelerate) AND we know the total distance traveled you can rewrite it as

v = A*sin ((2*pi*x)/ (2*D))

where
v - velocity value for a given distance during travel
A - maximum velocity ( say 300 pixels/sec)
x - is individual distance point (ex. if you want arrow to travel from 0 to 1000 pixels, x would be incremental values of 0,1,2,3,4,...998,999,1000; I used example with increment of 1 but you can change it to whatever suits you)
D - total distance traveled that you want (say 1000 pixels)

In your code limit x to maximum value of D to only get half a period.

HTH and makes sense :)

wow that's long!

phranque

8:12 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



i was off by a factor of 2.

to answer your question, remember that 1/4 cycle is 90 degrees which is pi/2.
so the area under a triangular wave would be pi/4 or about .785 and the area under a square wave is pi/2 or about 1.57 and the area under the sine wave is equal 1.0 for that period. (not 0.5 as i mistakenly wrote before)

therefore if the initial velocity is 10 inches/second and you stopped it in 0.5 seconds it will stop in 5 inches.

daveVk

11:16 am on Jan 17, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



if the initial velocity is 10 inches/second and you stopped it in 0.5 seconds it will stop in 5 inches

if you left the velocity unchanged it will travel 5 inchs in 0.5 seconds.

the integral for a sin wave is 1 as you state, over a period of pi/2.
the integral of 1 (constant motion) over some period is pi/2
therfore ratio of sin vs const = 2/pi

In other worlds you need to divide integral by period to get average.

phranque

2:01 pm on Jan 17, 2008 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



if you left the velocity unchanged it will travel 5 inchs in 0.5 seconds.

thank you for that "duh!" moment. =8)
i should get back to web stuff - it's been too long since i practiced that calc and diff eq stuff...

Dabrowski

9:39 pm on Jan 22, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Tastatura, thanks for the extended info, some I knew, some I didn't.

You can also use sinusoidal profile...

Yes, this is what I want.

You explained what I wanted a lot better than I did! One complete phase of the sine wave is up, down, down more, and up again.

What I'm using, as I'm sure many animators have done, is use the first 1/4 phase to speed up, the second quarter to slow down. So I'm left with a velocity curve that looks like an upside down. And yes, as per your suggestion I am using a variable to keep track of the curve, so I get to the top of the curve, then travel at constant speed, then switch back to the sinewave to do the second curve.

So, I guess what I'm asking, if I know the length of the profile, how do I calculate how long the sine parts will be?