The spring is sprung 17 April, 2008 at 7:21 am
More Flash fun, this time with balls on springs chained together. The example code in the book I’m reading suggested using trigonometric functions to calculate the ‘spring target’, but I thought I could do it with similar triangles.
Imagine two items (A and B) connected by a spring of a certain relaxed length (not stretched or compressed). It will help to think of item B as a fixed point and item A as the ‘free’ end of the spring. The item A will tend towards a point that is the relaxed length from B, in a straight line between A and B; it will be drawn towards B if pulled far away, and pushed away from B if it is too close. I’m assuming, of course, a massless spring and a whole bunch of other things – this is only a simple approximation of the very complex real world!
Here is the code:
var dx:Number = itemA._x - itemB._x;
var dy:Number = itemA._y - itemB._y;
if (dx || dy)
{
var d:Number = Math.sqrt(dx*dx + dy*dy);
var r:Number = springLength / d;
var targetX:Number = itemB._x + r * dx;
var targetY:Number = itemB._y + r * dy;
// ... other fun bits about the same
}
A diagram would probably help! :o)
Basically I’m using the fact that we have similar right-triangles, and am using a ratio of the relaxed length of the spring to the length of the hypotenuse instead of using atan2() to find an angle then sin() and cos() to extrapolate a position. I don’t have any sort of performance metrics on it (hey, Flash is generally pretty slow for anything), but I’m supposing it could help a bit.
The hardest parts of this little project have been trying to figure out how to get Flash to actually do something… or at least tell me why it isn’t doing something, and moving code into some custom classes proved quite painful. The result is quite nice, though, and I’ll build on the techniques developed here in later projects.
I noticed an increase in size with almost exactly the same functionality when I started moving code in to classes, which I was a little surprised by given that the classes allowed me to reduce code repetition. I’m supposing that using classes (accessing object methods, etc) impinges on performance, but even with only a few balls on springs things were starting to get ‘messy’. The new code breaks things down a lot better and will hopefully allow for integrating new ideas as I make my way to the next chapter…
The Flash movie is roughly five and a half kilobytes. You can grab the boxy handles, and ‘throw’ the balls around. Use the UP, DOWN, 0 (zero) and Z keys to change the gravitational constant used (a little anti-gravity can be fun!), and hit SPACE to assign random masses and positions to the balls, as well as random spring lengths and stiffnesses to the springs. You can’t change the connections just yet – maybe next time!
Flash link: springpixel_01.swf
-G.
Leave a Reply