« »

Shoots and Leaves

The online version of Shoots and Leaves is here. It uses the mouse and keyboard instead of a Wiimote.

BranchesFor my ICM final, I teamed up with the lovely and talented Michelle Mayer, and together, we set out to create something beautiful out of something repulsive. My initial idea to cause red flowers to explode in a messy splatter all over a screen if you aimed a gun at your own head while standing in front of said screen. That seemed derivative (that t-shirt of Itamar’s with the birds flying out of the guy’s head) and more of a PComp problem, so we restated the challenge as creating life out of death.

The idea became to create an algorithmic seed that once planted, would grow on its own in an unpredictable and unique manner. We planned to project onto a mannequin wearing a white shirt and shoot at it with a Wiimote. But instead of drawing blood, our shots would draw flowering vines. Not to get too meta-geeky here, but the idea and its visualization are more than a little reminiscent of Project Genesis in Star Trek 2: The Wrath of Khan

When creating the effects for the scene, Industrial Light and Magic had to invent a bunch of graphic technologies. And good old retinal scanning, oh brave new world that has such technologies in it!

Anyway, we wanted to do something similar. Our first thought was to use input from a Wiimote to trigger a series of video elements we would have created ahead of time, but Processing’s limitations when dealing with large numbers of simultaneous video clips, the prospect of spending even more time in After Effects, and Dan Shiffman’s encouragement to seek out a programmatic solution convinced us that we might as well program life. Our initial proposal is here.

Creating Branches

The first task we tackled was branching. If our flowering vines were going to be at all realistic, they would have to unpredictably spawn other branches as they grew. This was a matter of setting a series of necessary preconditions for branching and a probability of its occurrence once those preconditions were met. Then all we had to do was pass a point on an existing branch as the origin for a new branch instance. That actually wasn’t so difficult, thought initially, all the existing branches would branch simultaneously and with ever increasing frequency until the whole screen filled up exponentially. Adding a variable in each branch to keep track of its lifetime and randomly changing it upon a successful branch solved that.

Curved Paths

The next challenge was getting the branches to move in nice curvilinear paths that were nonetheless irregular. We spent an entire day playing with sine functions but to no avail, our vines looped like drunken rollercoasters. The solution occurred to me right as I was going to bed one night. Taking my cue from Craig Kapp’s brilliant gravity simulator, I thought, why not have a bunch of balls that exert a force on the growing branches bouncing around invisibly in the background? Have three, say, and when a branch is born, assign it to follow one randomly. Make the force proportional to the square of the distance and it should yield random-looking curved paths. And it did!

Aging: A Perennial Problem

Next we decided we wanted our branches to thicken with age, as they would in real life. This we accomplished by storing each branch’s last fifty x and y positions and then drawing fifty successively larger semi-transparent ellipses at each. This creates the illusion of a thickening that follows the branch’s sprout. It also slows things down a fair amount because of the memory it requires.

Switch Cases and Flowers

Our final design step involved implementing flowers and leaves (and little twirly tendrils which in our multi-day programming orgy we never quite figured out). Since the basic conditions for branching are no different from the conditions for sprouting leaves or flowering, we implemented a switch case that favored leaves:

          if (b.check()){  // If a branch hasn't just branched
            if (b.branchcount < 20) {  // and it hasn't already branched more than 20 times
              int chance = round(random(0,3)); // pick one of the following cases randomly
              switch(chance) {
              case 0:
                b.branch();  // spawn a new branch
                b.branchcount++;
                b.lifetime = -b.branchcount * 200;  // delays the time its going to take for the next new sprout from the same branch
                break;
              case 1:
                b.flower();
                b.branchcount++;
                b.lifetime = -b.branchcount * 200;
                break;
              case 2:  // two leaf cases to ensure more leaves than flowers and branches
                b.leaf();
                b.branchcount++;
                break;
              case 3:
                b.leaf();
                b.branchcount++;
                break;
              }
            }
            else {
              branches.remove(b);
            }

          }

We addressed several interesting smaller problems (rotating the leaves using the arctangent function to ensure that they grew according to the direction in which the branch was moving, implementing Wiimote control, and the eventually discarded use of real images of leaves and flowers instead of programmatically drawn ones) in Encroachment, which is documented here.

Here's Michelle showing the project on a wall at ITP:

Comments

Comments are closed.