2009
10.28

Noise in Color

Here’s a video of some stuff I’ve been playing w/ in Processing — this is an animation of a Perlin noise flow field. It’s only interesting because the step size of the z-coordinate is different than for the x and y coordinates.

Also, you can see it uses a rainbow color palette what to make it look pretty…

A couple of ideas have just occurred to me – one is that it might be neat to have different x and y step sizes. Also! It would be interesting to build flow-fields out of gray scale images… I might try that next just to see what happens.

2009
10.20

Photography

I bought a dead horse from a firm called Casualty Cattle in Derbyshire and had it brought back to my studio on a trailer. From that point on, things began to go wrong for me. Horses are actually quite a lot bigger than you think.

via

2009
10.18

Playing With Noise…

I’ve been goofing around with planes of perlin noise. I’m not going to post an applet because it seems most people can’t see them. So here’s a screen grab from the app…

Picture 1

I’m using Perlin Noise to generate this. I’m treating each point as an angle, generating the vector components, then storing it all in a screen-sized array. Then, I drop particles at random heights on the right-most part of the screen and update their positions from the vectors stored in the array. Then the drawing just sort of draws itself… It’s sort of like a giant game of Plinko.

2009
10.09


<br /> You need java for this to work.. :-/<br />

Some pretty ugly stuff, this:

 
ArrayList displays;
float currentAngle = 0;
float currentX = 200;
float tempX = currentX;
float currentY = 150;
float tempY = currentY;
WormThing w1 = new WormThing(250,400,0);
WormThing w2 = new WormThing(250,400,180);
 
class MouseDisplay { 
  float x,y;
  boolean alive;
  private int telomere;
  float rotation_angle;
  float rotation_speed;
 
  MouseDisplay(float x_, float y_, int size_) { 
    x = x_;
    y = y_;
    alive = true;
    telomere = size_;
    rotation_angle = 45;
    rotation_speed = 10;
  }
 
  void show() {
    x = x+cos(radians(rotation_angle)) * rotation_speed;
    y = y+sin(radians(rotation_angle)) * rotation_speed;
    rotation_angle -= 10;
    ellipse( x,y, telomere, telomere);
    telomere--;
    if (telomere == 0) {
      alive = false;
    }
  }
}
 
class WormThing { 
   float angle;
   float x;
   float y;
 
   WormThing(float x_, float y_, float angle_) { 
      x = x_;
      y = y_;
      angle = angle_;
   }
 
   void execute() { 
      angle += 5;
      x += cos(radians(angle)) * 15;
      y += sin(radians(angle)) * 15;
      for (int i = 1; i < 5; i++) { 
         MouseDisplay d = new MouseDisplay(x+random(-10,10), y+random(-10,10), 100);
         if (displays.size() < 250) {
            displays.add(d);
         }
      }
    }
 
}
 
void setup() {
  size(600,800);
  frameRate(30);
  stroke(90, 60, 50);
  smooth();
  displays = new ArrayList();
}
 
 
void draw() {
 
  w1.execute();
  w2.execute();
 
  background(167, 159, 148);
  for (int i = 0; i < displays.size(); i++) {
 
    MouseDisplay m =  (MouseDisplay) displays.get(i);
    m.show();
    if (m.alive == false) {
      displays.remove(i);
    }
  }
  print(displays.size()+"\n");
}
2009
10.05

Ok, so remember how yesterday I said I tried to draw this curve, but “everything went wrong” and here’s something random? Yes? Great!

What I was trying to get at is that there is more than one way to skin a cat or, if you prefer, to visualize a recursive set. In the last Koch example, the drawing code itself was recursive. We would see if we were at the terminal (bottom-most) depth and if so, draw a little bit of line. Otherwise, we would recursively call the drawCurve(…) function.

Instead of making the drawing code recursive, we can define the curve as a set of rules, evaluate those rules recursively, and use the Turtle from my last post to draw the whole curve!

The especially cool thing about this is that we can change the rules to draw whatever kind of self-similar shape we want, without having to do a bunch of math for each curve we want to draw.

About L-systems
An L-System is defined by a grammar. It has a starting state (sometimes called an axiom) and some rewriting rules. For the Koch curve, you’ll sometimes see the L-System defined like this:

Axiom: F
Rule: F -> F+F-F-F+F

I think people use pluses and minuses to make it look like math. Instead, you should think of each character in the Rule as an instruction for your turtle. F means “go forward”, + means turn left, – means turn right.

I wrote my Koch curve rule like this:

Axiom: f
Rule: f -> f l f r r f l f

For myself, “l” means turn left, and “r” means turn right.

Ok, so that’s all well and good, but how does this translate to a crazy self-similar curve? All I’ve shown you so far is a really simple grammar.

Well, the key is that the rule “f” rewrites itself. I’ll show you in the table below, for up to two iterations:

Iterations Result
0 f
1 f l f r r f l f
2 f l f r r f l f l f l f r r f l f r r f l f r r f l f l f l f r r f l f

Ok, so for each iteration, you replace ‘f’ with ‘f l f r r f l f’. Once you’ve iterated enough times, you can tell your turtle to follow the instructions in that list.

Trouble is, when you fully expand the list, you see that it gets really big after just a couple of iterations. If you tried to just string replace 10 times, you would run out of memory. And don’t think about trying to get more memory, because if you doubled your memory, you might have enough for just one more iteration.

So, the way to overcome this is to evaluate the rules while we’re drawing. You’ll find the code for that in the function called evalutron, below:

Turtle t;
HashMap rules;
 
class Turtle {
  float x, y, ang;
  float default_angle;
  boolean down;   
 
  Turtle(float _x, float _y, float _ang) { 
    x = _x;
    y = _y;
    ang = _ang;
    down = false;
  }
 
  void penDown() { 
    down = true;
  }
 
  void penUp() { 
    down = false;
  }
 
  void forward(float len) { 
    float nx = x+cos(radians(ang))*len;
    float ny = y+sin(radians(ang))*len;
    if (down) { 
      line(x,y,nx,ny);
    }
    x = nx;
    y = ny;
  } 
 
  void turnLeft(float _ang) { 
    ang -= _ang;
  }
  void turnLeft() {
    ang -= default_angle;
  }
 
  void turnRight(float _ang) { 
    ang += _ang;
  }
  void turnRight() { 
    ang += default_angle;
  }
}
 
void execute(char chr, float zoom_factor) { 
  switch (chr) { 
  case 'l':
    t.turnLeft();
    break;
  case 'r':
    t.turnRight();
    break;
  case 'f':
    t.forward(zoom_factor);
    break;
  }
}
 
void evalutron(String state, HashMap rules, int depth, float zoom) { 
  for (int i = 0; i < state.length(); i++) { 
    char x = state.charAt(i);
    String result = (String) rules.get(x);
    if (depth > 0 && result != null) { 
      evalutron(result, rules, depth-1,zoom);  
    }
    else { 
      execute(x, zoom);
    }
  }
}
 
void setup() { 
  background(10);
  stroke(120);
  smooth();
  size(600,600);
  frameRate(30);
  /** 
   * Set up the L-System Rule
   */
  rules = new HashMap();
  rules.put('f', "flfrrflf");
  /** 
   * Configure our friendly turtle 
   */
  t = new Turtle(0,300,0);
  t.penDown();
  t.default_angle = 60;
  /*
   *  Evaluate the rule set, and draw the curve.
   *  'f' is the initial rule set. notice that 'f' is the rule in the rules map, 
   *  so it will get rewritten for each iteration.
   */
  evalutron("f", rules, 7, .28);
}

You see that evalutron just looks at the current token, evaluates the depth at which its evaluating, and decides whether to expand the current token to another ruleset, or to pass the command to the turtle. Easy as pie!

Oh, and if you’re paying very close attention, you’ll see that the turtle has changed a teeny bit: he can now turn a ‘default’ amount by calling turnLeft() and turnRight() with no parameters.

So anyways, this is another way to draw cool recursive sets, but in a way that’s a little more language-y and a little less math-y. Also, you can change the original ‘axiom’ or add new rules to get wildly different results. Try it!

As proof, here’s the applet in action. Sorry, no interaction this time:


<br /> You need java for this to work.. :-/<br />

2009
10.05

I Made A Turtle!

I was trying to make a demonstration of how to do a Koch curve as an l-system with turtle graphics, but my computer would run out of memory when I set it to 3 iterations, because I would rewrite the rule back into the original string that contained the “what’s yr turtle gonna do” information. Maybe another day…

But anyways, I made a Turtle. Here it is doing a random forward/backward walk (+/- 10 pixels) and turning left one degree for every frame. It’s oddly compelling to watch.

Oh hey, if your turtle wanders off the screen (unlikely in the short term, inevitable in the long term, sort of like death…) then just click on the applet to reset him back to the middle of the screen.

Also, thanks to my Mom for getting me a “Programming with LOGO book” when I was still a toddler. Apparently, those lessons weren’t lost on me…

<br /> You need java for this to work.. :-/<br />

Turtle t;
class Turtle {
  float x, y, ang;
  boolean down;   
 
  Turtle(float _x, float _y, float _ang) { 
    x = _x;
    y = _y;
    ang = _ang;
    down = false;
  }
 
  void penDown() { 
    down = true;
  }
 
  void penUp() { 
    down = false;
  }
 
  void forward(float len) { 
    float nx = x+cos(radians(ang))*len;
    float ny = y+sin(radians(ang))*len;
    if (down) { 
      line(x,y,nx,ny);
    }
    x = nx;
    y = ny;
  } 
 
  void turnLeft(float _ang) { 
    ang -= _ang;
  }
 
  void turnRight(float _ang) { 
    ang += _ang;
  }
}
 
void setup() { 
    background(10);
    stroke(120);
    smooth();
    size(600,600);
    frameRate(30);
    t = new Turtle(300,300,0);
}
 
 
void draw() {   
    if (mousePressed) { 
        t = new Turtle(300,300,0);
    }
    t.penDown();
    t.forward(random(-10,10));
    t.turnLeft(1);
}
2009
10.04

Mirrored Koch Curve

So this is kind of cool. I spend a little time last night goofing around w/ Processing, which I haven’t used since I was in college. And back then, I had a pentium II 400Mhz computer running Windows, so I wasn’t able to get a lot of use out of it. Anyways, here’s an interactive Koch curve. Move you mouse over the applet to activate. Moving your mouse to the right increases the angle of the curve, moving it up and down increases or decreases the number of iterations of the curve. Have fun! The code follows the demo:


<br /> You need java for this to work.. :-/<br />

void drawCurve(float x, float y, float len, float ang, float curve_angle, int depth) { 
   float sideLen = (len/6) / cos(radians(curve_angle));
   float ax = x+cos(radians(ang)) * len/3;
   float ay = y+sin(radians(ang)) * len/3;
   float bx = ax+cos(radians(ang-curve_angle)) * sideLen;
   float by = ay+sin(radians(ang-curve_angle)) * sideLen;
   float cx = bx+cos(radians(ang+curve_angle)) * sideLen;
   float cy = by+sin(radians(ang+curve_angle)) * sideLen;
   float dx = cx+cos(radians(ang)) * len/3;
   float dy = cy+sin(radians(ang)) * len/3;
   if (depth > 0) { 
     depth--;
     drawCurve(x,y,len/3,ang,curve_angle,depth);
     drawCurve(ax,ay,sideLen,ang-curve_angle,curve_angle,depth);
     drawCurve(bx,by,sideLen,ang+curve_angle,curve_angle,depth);  
     drawCurve(cx,cy,len/3,ang,curve_angle,depth);
   } else {
     line(x,y,ax,ay);
     line(ax,ay,bx,by);
     line(bx,by,cx,cy);
     line(cx,cy,dx,dy);
   }
}
 
void setup() {
  size(800,600);
  frameRate(30);
  background(0);
  smooth();
  stroke(60);
}
 
void draw() {
  background(0);
  float curve_angle = (90*mouseX/800);
  curve_angle=min(70,curve_angle);
  int detail_level = 7-(int) 8*mouseY/600;
  drawCurve(0,  300, 800, 0,  curve_angle, detail_level);
  drawCurve(800,  300, 800, 180,  curve_angle, detail_level);
}