Inertia Javascript

dust's picture

does anyone know an easy way to do inertia in javascript ? i know qc has inertia built in which is fine but i'm making an iPad app that is is a remote for qc so the controls need to be the same on both. i'm using inertia in qc. i know the iphone has inertia scrolling so maybe someone knows some stock sdk code for inertia or how to do in javascript in qc.

im going to experiment.

would this work. ?

d = (p2-p1);

s = 8;

inertia = ((inertia += d) / s));

s being the speed variable. i really want to incorporate friction as well.

any help would be awesome.

i've been poking around paul bourkes site thinking he may have a function.

im going to poke around some BBCode and see if i can find a inertia function.

maybe look for a framework or something ?

it doesn't matter what language. i said java script because i can convert javascript to what ever language i want.

help please. i know someone out there has a function built.

toneburst's picture
Re: Inertia Javascript

No answers, I'm afraid, but I'm watching this thread, because I'm looking for something similar myself. Paul Bourke's site does have lots of interpolation functions. What you're essentially after is a way of applying these to consecutive values. I'm fairly certain a straight linear interpolation is relatively easy to do, but some of the other interpolation types in offered by the QC Smooth patch are probably a bit more complicated. You must be able to find recipes for this kind of thing somewhere, but, like you, I've so far not managed to find them.

a|x

toneburst's picture
Re: Inertia Javascript

The equation above looks right to me, incidentally. That would give you a straight linear interpolation, as far as I can work out. You could then use that to step through any other kind of interpolation curve (exponential for example) to simulate friction.

As always, I'm vague on the maths involved though.

a|x

toneburst's picture
Re: Inertia Javascript

Try this simple linear smooth:

var oldValue = 0;
 
function (__number Smoothed_Value) main (__number Value, __number Smooth, __number _dummy)
{
   var outValue = oldValue + ((Value - oldValue) * Smooth);
   oldValue = outValue;
 
   var result = new Object();
   result.Smoothed_Value = outValue;
   return result;
}

where 'Smooth' is a value in the range 0 > 1 (0 being infinitely smoothed, and 1 being no smoothing). You might want to invert the smooth value so a larger value gives more smoothing (which seems more logical), or add an Interpolation patch to the Smooth input so you can set the range and curve of that control to give meaningful results (or code your own interpolation curve for this control).

Incidentally, I'm not sure if this method is 'Iterator-safe'. I've been caught out before attempting to use JS patches inside an Iterator. I'd be interested to know if this should work inside one or not (by which I mean, provide independent smoothing per-iteration)....

a|x

toneburst's picture
Re: Inertia Javascript

Example QTZ.

a|x

PreviewAttachmentSize
tb Linear Smooth JS.qtz4.29 KB

gtoledo3's picture
Re: Inertia Javascript

tb, have you ever thought about handling smoothing a whole structure? The idea being that one could feed a patch static structures, or have a few structures hooked to input ports... and that as each structure is chosen, values smoothly morph from one to another.

(sorry for getting a bit OT from inertia, Dust).

Since smooths/iterators work, and published outs work, I've actually made a macro that handles a 3 element structure with an arbitrary amount of indexes, but boy, performance sure sucks with anything non trivial. I would love to figure out how to smooth structure of an arbitrary amount of indexes, with 3 or 4 (or whatever) elements.

If I do the same basic idea, but have the renderer inside of the iterator, and don't convert back to structure...performance is still crappy, but bearable.

(Actually, this begs the thought... maybe I should try putting the queue outside of the iterator, though that isn't what was recommended in the docs.)

PreviewAttachmentSize
Structure Smooth Example.qtz10.28 KB

dust's picture
Re: Inertia Javascript

so the dummy is to keep the js patch evaluating ?

dust's picture
Re: Inertia Javascript

i like how you interpolated the speed curve to ease out.

thanks tb.... your the best... haven't got much sleep lately and was having a hard-time figuring out smoothing in my head.

so friction is arbitrary just like speed is and all i have to do step through again ?

dust's picture
Re: Inertia Javascript

this is perfect as i all ready have made an interpolation curve function.

usefuldesign.au's picture
Re: Inertia Javascript

Funnily when I was reading your 3D queue JS patch I was like, that "if (_Queue.length > Size) _Queue.splice(0,_Queue.length-Size);" doesn't look like gt js code to me, then I read the credits!

usefuldesign.au's picture
Re: Inertia Javascript

I thought I'd wait for others to have a go at this first because I'm not to sure about the maths of friction these days. The inertia equation is fine for friction-less mechanics. I think you might have to use energy equations if you want to simulate friction (unless you just approximate it by bleeding speed over time (S -= bleed)).

Kinetic energy will be reduced by friction (entropy). Work out how much energy your system is leaking (will be dependant on speed and friction co-efficient I guess) then subtract that from the current kinetic energy of object. So using Kinetic Energy, KE = m.v.v/2, you can calculate a delta in KE (Kinetic Energy) to a delta in v (speed).

The friction calculation can be as simple or complex as you like to make it. Linear with more speed equals more friction (like pushing a boat), linear with more speed equals less friction (like when you pull a tablecloth off a table of objects). Or non-linear simulating drag (fluid mechanics) (high drag at high and low speeds with a low drag sweet spot in the middle would probably suit you best). See http://en.wikipedia.org/wiki/Drag_(physics) & http://en.wikipedia.org/wiki/Parasitic_drag

This is schoolboy physics but I did it twenty years ago so not to fresh on the details (ouch).

One of the first QC comps I examined was on the qc list; somebody had posted a comp that was simulating iPhone type horizontal scrolling with a row of thumbnail images loaded form a directory. I've since wanted to look at it again but can't ever think of a good enough search token to find it in the archive. The author was looking for help with it but the motion part was operational and it just used std patches (like smooth) not js patch (if memory serves).

toneburst's picture
Re: Inertia Javascript

I think you could simulate friction reasonably well by doing custom interpolation curves, like the ones used by the existing Smooth patch. I'm going to try a 1D Bezier interpolation method as soon as I get a chance, which should allow for ease-in/ease-out type interpolation curves. It should also be relatively easy to have different interpolation for rising and falling values, as the Smooth patch has.

I'll get back to you as soon as I've had a chance to work on it. Was hoping to do some work on it here at work today, but it's not going to happen, unfortunately.

a|x

dust's picture
Re: Inertia Javascript

i wasn't thinking smooth was related to inertia even though they have the same sort of effect. man usefuldesigns sent me on a wiki hunt. i ended up trying a method "delta-v" its astrodynamics or areo dynamics or something.

wikipedia is funny. i just want to move a circle around my ipad screen with some inertia and wikipedia is like this is how to calculate drag velocities for making rockets and once you get the delta you then use that to formulate the flight trajectory path of your rocket. all i need to do now is figure out how to make rocket fuel...

either way the math was easier and was basically the same thing i had in my head. simplified its (v2-v1). so after reading up on some dynamics i got a better understanding of dynamics works. the only thing i have done for physics is in c++ class we had to implement a van der wall gas algorithm. (might be interesting with fluid dim) which i had a little trouble with...

as i have no problems converting physics algebra to machine language but solving things in my head to write the algorithm was hard as i haven't really done any college math yet. well besides logic and cos which i get a++ because i make up implicative laws for fun.

whats the best kind of math class to take for qc related tasks. like i want to be able to arbitrarily write parametric equations from my head. is that calculous ???? just practice ? is it trig... i get confused as all the math stuff kind of bleeds together in the qc context...

thanks guys... i have been messing with physics simulations for years in maya but never understood how all that is working behind the scene's.

toneburst's picture
Re: Inertia Javascript

No idea, mate. I have maths-blindness, I'm afraid :(

Stuff I do know:

  1. matrices are pretty handy for 2D/3D transformations, and also are very important in general 3D graphics (including OpenGL).

  2. there's a hell of a lot of other stuff out there I should know, but don't...

a|x

dust's picture
Re: Inertia Javascript

got some sleep. feel much better. here is a smooth function i came up with. it has increasing and decreasing values.

smooth code

  1. float smoothed(float value, float lastValue, float increasingScale, float decreasingScale)
  2. {
  3.  
  4. if(value > lastValue)
  5. {
  6. lastValue += increasingScale * (value - lastValue);
  7. return lastValue;
  8. }
  9. else if(value < lastValue)
  10. {
  11. lastValue += decreasingScale * (value - lastValue);
  12. return lastValue;
  13. }
  14.  
  15. }

interpolation code with curve..

  1. float interpolate(float originalMin, float originalMax, float newBegin, float newEnd, float inputValue, float curve)
  2. {
  3. float OriginalRange = 0;
  4. float NewRange = 0;
  5. float zeroRefCurVal = 0;
  6. float normalizedCurVal = 0;
  7. float rangedValue = 0;
  8. float invFlag = 0;
  9. float result = 0;
  10.  
  11. if (curve > 10) curve = 10;
  12. if (curve < -10) curve = -10;
  13.  
  14. curve = (curve * -.1) ;
  15. curve = pow(10, curve);
  16.  
  17. if (inputValue < originalMin)
  18. {
  19. inputValue = originalMin;
  20. }
  21. if (inputValue > originalMax)
  22. {
  23. inputValue = originalMax;
  24. }
  25.  
  26. OriginalRange = originalMax - originalMin;
  27.  
  28. if (newEnd > newBegin)
  29. {
  30. NewRange = newEnd - newBegin;
  31. }
  32. else
  33. {
  34. NewRange = newBegin - newEnd;
  35. invFlag = 1;
  36. }
  37.  
  38. zeroRefCurVal = inputValue - originalMin;
  39. normalizedCurVal = zeroRefCurVal / OriginalRange;
  40.  
  41. if (originalMin > originalMax )
  42. {
  43. result = 0;
  44. return result;
  45. }
  46.  
  47. if (invFlag == 0)
  48. {
  49. rangedValue = (pow(normalizedCurVal, curve) * NewRange) + newBegin;
  50. }else{
  51. rangedValue = newBegin - (pow(normalizedCurVal, curve) * NewRange);
  52. }
  53.  
  54. result = rangedValue;
  55. return result;
  56.  
  57.  
  58.  
  59. }

and here is my objc++ implementation i still had to go with apples ease out timing function as the smooth and interpolation just made things a little smoother. not sure if in cocoa i have to feed a time into my function to stop the lazy eval like in qc ? here is a touch event snippet.

  1. float x = smoothed(x, prevloc.y, .1, .1);
  2. float y = smoothed(y, prevloc.x, .1, .1);
  3.  
  4. float sx = interpolate(0, 1024, -1, 1, x, 0);
  5. float sy = interpolate(0, 780, -.7, .7, y, 0);
  6.  
  7. float rad = atan2(sx,sy)+3.14159265358;
  8.  
  9. if (x > 262 && x < 762 && y > 140 && y < 640 )
  10. {
  11. [rec.layer setValue:[NSNumber numberWithFloat:rad]
  12. forKeyPath:@"transform.rotation"];
  13.  
  14. CABasicAnimation* slow2Stop;
  15. slow2Stop = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  16. slow2Stop.toValue = [NSNumber numberWithFloat:interpolate(0, 6, 0, 6, rad, .1)];
  17. slow2Stop.duration = 1;
  18. slow2Stop.cumulative = NO;
  19. slow2Stop.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  20.  
  21. [rec.layer addAnimation:slow2Stop forKey:@"rotationAnimation"];
  22.  
  23. [record attachArgument:[BBOSCArgument argumentWithFloat: interpolate(0, 6, 0, 1, rad, 0)]];
  24. [[self oscSender] sendOSCPacket:record];
  25.  
  26. NSLog(@"radians clockWise %f",rad);
  27.  
  28. }
  29.  
  30. else if (rad > 1 && rad < 3 ) {
  31.  
  32. [rec.layer setValue:[NSNumber numberWithFloat:rad]
  33. forKeyPath:@"transform.rotation"];
  34.  
  35. CABasicAnimation* slow2Stop;
  36. slow2Stop = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
  37. slow2Stop.toValue = [NSNumber numberWithFloat:rad*-1];
  38. slow2Stop.duration = 1;
  39. slow2Stop.cumulative = NO;
  40. slow2Stop.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
  41.  
  42. [rec.layer addAnimation:slow2Stop forKey:@"rotationAnimation"];
  43.  
  44. [record attachArgument:[BBOSCArgument argumentWithFloat: interpolate(0, 6, 0, 1, rad, 0)]];
  45. [[self oscSender] sendOSCPacket:record];
  46.  
  47. NSLog(@"radians CounterClockWise %f",rad);
  48. }

so yeah the principles apply to structures as well. even audio i'm looking into an averaging smooth right now.

dust's picture
Re: Inertia Javascript

here is how you do acceleration velocity calculations based for rotations.

float angleRad =  atan2(sx,sy)+3.14159265358;
         float lastAngleRad =  atan2(prevloc.x,prevloc.y)+3.14159265358;
         float deltaTime = 2;
 
         float angleVelocity = ((angleRad - lastAngleRad) / 2*M_PI) / deltaTime;
         float accelerationVelocity = (angleVelocity - lastAngleRad) / deltaTime;

the credit for this goes to martin's specifications of the tuio protocol.

gtoledo3's picture
Re: Inertia Javascript

It was originally :

if (_Queue.length > Size) _Queue.shift()

...Which will only enlarge a queue size. This came from the mouse ribbon example qtz.

With some back and forth from Steve, he pointed out the splice function, and I integrated it into the example.

The cool thing about doing a queue like this is that you can adjust it to take image structure, and then do multiple channels, so to speak...

usefuldesign.au's picture
Re: Inertia Javascript

Custom curve in the interpolation patch would do it. If somebody wants to draw a curve rather than define it mathematically, this is the wave to go. And fluid dynamics equations are kind of complicated because of the feedback nature of velocity and drag (almost a complex system but not quite).*

You can even 'call subroutine function' from the javascript code to the interpolate curve patch using an output to feed the variable out and an input to receive the curve function back in. It will take one run cycle to execute I guess so it's always a frame behind but this is no drama in any case I have used this.

I'll post a comp to show what I mean but it's just like the recursion demos we were doing on another thread, output velocity (S) to an interpolate patch and then receive the new velocity adjustment factor at an input which is then calculated for new velocity passed to the output (S) along with any changes due to user interaction. Curve might start at (0,0.5) slide to (0.4,0.2) then climb to (1,1) using exponential/quadratic/cubic shaping (Ek =v.v.m/2 would imply quadratic curves ie. y=a.x.x + b.x + c but I might be missing something here)

  • In high school ('84/5!) we had to do a hand calculated and drawn plot of a cricket ball thrown into the air with a given velocity and at a given angle to ground. We had a spreadsheet like grid of equations including air viscosity, v.x, v.y etc etc across the top of an A4 landscape and had to use a calculator to do all the equations for every 0.1 of a second until the ball landed. I had access to an early spreadsheet app on a 512K Mac so did it that way then plotted the data on an HP plotter at my Dad's physics lab. The curve had totally realistic looking shape ;)

usefuldesign.au's picture
Re: Inertia Javascript

gtoledo3 wrote:
The cool thing about doing a queue like this is that you can adjust it to take image structure, and then do multiple channels, so to speak...

Are you saying JS patch can handle structures including the image data type? I haven't ever needed to try that, I think. Sorry if I'm being dumb, not really sure what you're getting at... sounds interesting though, please clarify!

usefuldesign.au's picture
Re: Inertia Javascript

Hey Dust

The Grapher app that shipped with Leopard (and earlier I think) is an excellent place to start. It has demo equations that you can play with. Some of them a very complicated! But you can start with y = x+1 and go from there. Heaps of good maths site on web for school/colledge/uni level stuff. Maths Forum is good for asking questions, although if you stray from the text book type learning don't expect much company.

Best Alastair

gtoledo3's picture
Re: Inertia Javascript

Yeah, definitely. The javascript patch can be used to make structures of images including, but not limited to, image queues. It can be a nice convenience... and it doesn't have to be a queue like in this example either.

If one has a bunch of different destinations they are rendering onto, sometimes it can make sense to build up the image into an image structure, and then use automation of structure indexes (with or without iterator... the iteration in the attachment is simply a convenience) to control what hits each renderer at a given moment.

If I have something come up where I find myself wanting to make multiple image queues (or some other type of queue), I would almost always revert to doing it this way, as I feel like it tends to perform better than placing multiple stock queue patches.

Another rarer limitation of the stock queue patch that came up earlier this week; I found an instance where the stock patch when input with numeric data was outputting a structure like it should, but instead of it being a structure of normal numeric data like it would be in most cases, something about it being published out of the iterator was turning the values into a virtual QC numeric data type that was creating exceptions when input into anything that would normally take numeric input. Weird. I haven't seen anything quite like it, and should replicate it, come to think of it. If the queue was outside the iterator, it created the right type of numeric data, it just didn't work with the setup properly. However, when implementing a javascript queue, it worked 100% correctly, and data type was properly preserved.

PreviewAttachmentSize
javascript image queue.qtz10.28 KB

dust's picture
Re: Inertia Javascript

yeah i mess with grapher sometimes. i can get some pretty cool looking arbitrary equations going. every-time i try to convert them to qc they don't work or don't look as cool. i think there is some fundamental principle im missing in relation to the quartz composer context that is different in the grapher. if you want to see something cool in grapher. graph an equation, open qc then go to the make animation option in grapher and watch the gl buffer glitch out.... try at your own risk.

so thanks for the link. i think my problem is that some of the simbols are unfamiliar to me as just the ones that are used in computer science that im familiar with like sum lim infinity delta etc.. once i get the notation down which sometimes seems to be arbitrary and once i get all the symbols down i think i will be all set at converting anything i want from wikipedia.

i just want to be able to visualize arbitrary equations in my head like i can with predicate calculus or what ever they are calling semantic fuzzy logic these days. for instance i am able to arbitrarily write and visualize equations like this.

"¬(p=>q)=>(pvq) <=> ¬(pvq)=>(p=>q)"

this is a law i made up. you can check it, its a tautology, not referential tautology in a philosophical since but tautology of absolute truth like the laws of boolean just a bit more complex. so if i can do arbitrary equations im pretty sure i will be able to do them parametrically in my head.

here is an attempt at converting the above mentioned law to machine language.

boolean   t=(a==(c-1));
boolean f=(c==(a+1));
 
if(((t?f:false)?(t||f==false||true):true)==(!(t||f==true||false)?(t?f:true):true)){return true;}
else {return false;}
PreviewAttachmentSize
Screen shot 2010-05-13 at 12.38.31 AM.png
Screen shot 2010-05-13 at 12.38.31 AM.png452.57 KB

dust's picture
Re: Inertia Javascript

i found the best way to get a stock patch work in an iterator is to only use the iterator to fill values then publish the queue output inside the iterator then feed that structure into another iterator back up a level to draw your structure. at least in qc4 that is as qc 3 did not let you make iterator outputs.

usefuldesign.au's picture
Re: Inertia Javascript

Cool, I hate it when you guys show off video camera input patch, no go for me ;)

dust's picture
Re: Inertia Javascript

I take it that you are running a mini or tower without a cam. The patch posted qeues up a bunch of image frames and plays them back in a grid. The queue creates a nice image delay which looks cool when there is a contact sheet per say of images as you see delay cycle.