Cardinal splines in ActionScript (Updated)

Algorithms, Flex, Source Code,
8/20/07

Here’s the code driving the cardinal spline function I mentioned in the post last week on visual prototyping with Flex. ActionScript already has a bezier drawing method called “curveTo,” but it obliges you to specify a control point for every anchor point you add to the curve. This is great for precision, but sometimes you just want to run a smooth curve through a bunch of points without having to figure out where all the control points should be.

That’s what’s great about the cardinal spline—the next and previous points on the curve function as the control points.  (This means you need to add an extra point to the beginning and end of the curve, as you can see in the diagram accompanying the Wikipedia entry for c-splines.) You also get a “tension” parameter which allows you to set how taut the curve is between points.

I’ve included my current incarnation of this routine below.  Here’s how to use it:

  1. Start with an array of values you want to run the curve through: 3, 7, 2, 6
  2. Duplicate the start and end values: 3, 3, 7, 2, 6, 6
  3. Iterate through each pair of the original values, each of which represents a segment of the curve: 3-7, 7-2, 2-6
  4. For each of these iterations, proceed along the curve n number of steps (more steps = a smoother curve)
  5. Call this function at each step to get the value of the curve at that step

If you’re using the function to set the location of a sprite, then you’ll need to maintain two lists of values (one for x position, one for y position) and call the function once for each list as you’re iterating through each segment of the curve.

Update: Here’s an .fla example that uses the function to draw a curved line through twenty random points.

Here’s the source for the function itself:

/** 
 * Returns a value at the given step on the cardinal spline between two other values. 
 * 
 * @param prevVal  The point just prior the curve segment we are evaluating. 
 * @param startVal     The starting point of the curve segment we are evaluating. 
 * @param endVal       The ending point of the curve segment we are evaluating. 
 * @param nextVal  The point just after the curve segment we are evaluating. 
 * @param numSteps     Number of steps in the curve segment. 
 * @param curStep  The current step in the curve segment. 
 * @param easing       Type of interpolation to be applied to the curve segment. 
 * @param tension  How taut the curve is (0 = straight, 1 = curvy) 
 */ 
function getCardinalSplinePoint(prevVal:Number, startVal:Number, endVal:Number, nextVal:Number, numSteps:Number, curStep:Number, easing:String, tension:Number):Number {

    var t1:Number; 
    var t2:Number;
   
    switch (easing) {
   
        case “easeinout”: 
        t1 = endVal - prevVal; 
        t2 = nextVal - startVal; 
        break;
       
        case “noease”: 
        t1 = 0; 
        t2 = 0; 
        break;
       
        case “easein”: 
        t1 = 0; 
        t2 = nextVal - startVal; 
        break;
       
        case “easeout”: 
        t1 = endVal - prevVal; 
        t2 = 0; 
        break; 
    }
   
    t1 *= tension; 
    t2 *= tension;
   
    var s:Number = curStep / numSteps; 
    var h1:Number = (2 * Math.pow(s,3)) - (3 * Math.pow(s,2)) + 1; 
    var h2:Number = -(2 * Math.pow(s,3)) + (3 * Math.pow(s,2)); 
    var h3:Number = Math.pow(s,3) - (2 * Math.pow(s,2)) + s; 
    var h4:Number = Math.pow(s,3) - Math.pow(s,2);
   
    var value:Number = (h1 * startVal) + (h2 * endVal) + (h3 * t1) + (h4 * t2);
   
    return value; 
} 

 

Flex for visual prototyping

Digital Humanities, Experiments, Flash, Flex, Interactive Design,
8/17/07

This is one reason why I’m really digging Flex right now. I’m in the design phase with Sharon Daniel on a follow-up project to Public Secrets and we’re talking about dynamically generating a large number of curved forms as part of the design. All well and good, but how do I mock up the curves without drawing a million squiggly lines by hand? Easy—build a little Flex app that lets me set the parameters of the curve and generate as many as I want, then take screenshots and bring them into Photoshop. This is my first app using this many controls, and it only took a couple hours to put together. There’s a lot of ways in which Flex makes building this kind of thing feel as easy as it really should.

The curve is drawn using a cardinal spline algorithm (Update: c-spline source code) I first ported to Lingo back when I was working on Chroma, and then to ActionScript a couple years ago for Mobile Figures. I like it because it’ll run a smooth curve through any number of values without you needing to specify separate control points.

Check out the app: Curve Designer

Curve Designer application

 

Eloquence, evangelism, and the fourth wall

Games, Interactive Design,
8/15/07

Eloquence is a wonderful paradox—it’s both impossible to attain and impossible to escape.  Professional communicators spend their lives in pursuit of eloquence in specific domains, never feeling they’ve quite “arrived.”  Yet at the same time every event, being the instantaneous product of the current state of reality, can’t help but be eloquent of the moment in which it arises.  Of course, the distinction has to do with context.  Those with a vocation for eloquence often try to reduce the burden of context as much as possible; within their target audience, their aim is to reach as many people as they can (and the way in which they define their target audience—consciously or not—makes all the difference).  “Naive” eloquence has no such aspirations, and as such its recognition depends solely on the eye of the beholder.

There’s things I want to say in this life, and there’s people I want to work for who have their own things to say as well. Since interactive media are my vocation, it’s my goal to become more eloquent in my use of those media, not just for the sake of having marketable skills but because eloquence in the right place at the right time can be transformative.  Equally as important as developing my own eloquence, however, is advancing in my ability to find it in others. Justice is tightly bound to acknowledgments of eloquence from unexpected sources, and since everything is eloquent of something if only you’re prepared to see it, then the act of readying yourself to recognize unfamiliar eloquence is something of an imperative.

There’s no substitute for the uncomfortable process of immersing yourself in something foreign for a long enough period of time that you begin adopt some of its sensibilities—and thus its eloquence—as your own. What interactive media can provide, however, are “bridge experiences” that allow a person to temporarily adopt a shadow of someone else’s eloquence and thereby recognize it as such. Any quality communication can accomplish this, but interactive media does it in a uniquely tactile way in which you can literally feel and play your way through the contours of someone else’s fluency.

It’s easy to forget that this is what it’s all about. As authors of interactive media we can waste a lot of time trying to make sure everybody knows how articulate we are, when in reality the state of our skills can’t help but be revealed in the work, whether we like it or not. On any given project, commercial or otherwise, we’re tasked with representing a particular kind of eloquence; what’s most important is to ask what we’ve done to enable others to make that eloquence their own.

Sometimes, the things we have to do to accomplish that seem antithetical to how we want to feel about our own work; we want to possess the mystique of the artist, we want to keep things hidden, we don’t want to appear too overt or even helpful. All of which would be valid desires if our feelings were important. But in fact, and again paradoxically, the ability of a particular piece to accomplish what it needs to often depends directly upon our own annihilation.

When Shigeru Miyamoto breaks the fourth wall and has a character tell you to “press the A button to jump” it’s like an evangelist asking you if you know Jesus. Our insides twist up: we don’t really have to do it this way, do we? There’s got to be more subtle, more reasoned, more sophisticated ways to discuss these questions, don’t there?

Perhaps. But in the end, that only matters if your feelings matter in comparison to what the work needs to accomplish. And there’s a distinct possibility that they don’t.

 

Page 2 of 3 pages  < 1 2 3 >