marimonda – LineWalk

a perfectly ordered line gets tickled

I have been recently interested in space-filling structures, in particular fractals and reaction-diffusion patterns. For my project, I decided to code a Hilbert Curve and play around with its structural integrity with Perlin noise and mouse input. This way, the resulting curve was also an interactive experience.

What I found hard: finding the perfect amount of chaos and order proved to be the hardest part, I spent a really long time trying to alter each parameter.

A few more images, gifs + code  under the cut:

 

 

  

 

 

import processing.svg.*;
int order = 8;
int size = int(pow(2, order));
int total = size * size;
float noise_x_dimension = 0.0;
float noise_y_dimension = 0.0;
PVector[] path = new PVector[total];
int closest_power = 512;
int w = 600;
int offset = (w - closest_power)/2;

void setup() {
  size(600, 600);
  background(255);
}

void draw() {
  background(255);
  noise_x_dimension = map(mouseX, 0, w, 0.0,1.0);
  noise_y_dimension = map(mouseY, 0, w, 0.0,1.0);
  float len = closest_power / size;

  for (int i = 0; i < total; i++) {
    path[i] = hilbertCurve(i);
    path[i].mult(len);
    path[i].add(len/2, len/2);
  }
  stroke(0);
  strokeWeight(1);
  noFill();
  
  if(mousePressed){
    beginRecord(SVG, "linewalk.svg");
  }
  beginShape();
  float x, y;
  float map_x = 45;
  float map_y = 45;
  vertex(offset+path[0].x + map(noise(noise_x_dimension),0,1,-map_x,map_x),offset/2);
  for (int i = 0; i < path.length; i++) {
    stroke(0);
    if ((noise(noise_x_dimension) > 0.6)/*&&(noise(noise_y_dimension) > 0.5)*/) {
      x = offset+path[i].x + map(noise(noise_x_dimension),0,1,-map_x,map_x);
      y = offset+ path[i].y + map(noise(noise_y_dimension),0,1, -map_y,map_y);
    } else{
      x = offset+path[i].x;
      y = offset+ path[i].y;
    }
    curveVertex(x,y);
    noise_x_dimension = noise_x_dimension + 0.5;
    noise_y_dimension = noise_y_dimension + 0.001;
    //noise_x_dimension = tan(map(i,0,path.length,3,-1));
    //noise_y_dimension = tan(map(i,0,path.length,-1,3));
  }
  vertex(offset+path[path.length - 1].x + map(noise(noise_x_dimension),0,1,-2,2),offset/2); 
  // WIDTH
  /*for (int i = 0; i < path.length; i++) {
    stroke(0);
    if (noise(noise_x_dimension) > 0.75) {
      x = closest_power - (path[i].x + map(noise(noise_x_dimension),0,1,-map_x,map_x) - offset);
      y = offset+ path[i].y + map(noise(noise_y_dimension),0,1,-map_y,map_y);
    } else{
      x = closest_power - (path[i].x - offset);
      y = offset+ path[i].y;
    }
    curveVertex(x,y);
    noise_x_dimension = noise_x_dimension + 0.5;
    noise_y_dimension = noise_y_dimension + 0.001;
    //noise_x_dimension = tan(map(i,0,path.length,3,-1));
    //noise_y_dimension = tan(map(i,0,path.length,-1,3));
  }*/
  //vertex(closest_power - (path[path.length-1].x +map(noise(noise_x_dimension),0,1,-2,2) - offset),offset/2);
  endShape();
  if(mousePressed){
    endRecord();
    noLoop();
  }
  
}


PVector hilbertCurve(int i) {
  PVector[] points = {
    new PVector(0, 0), 
    new PVector(0, 1), 
    new PVector(1, 1), 
    new PVector(1, 0)
  };

  int index = i & 3;
  PVector v = points[index];

  for (int j = 1; j < order; j++) {
    i = i >>> 2;
    index = i & 3;
    float len = pow(2, j);
    if (index == 0) {
      float prev = v.x;
      v.x = v.y;
      v.y = prev;
    } else if (index == 1) {
      v.y += len;
    } else if (index == 2) {
      v.x += len;
      v.y += len;
    } else if (index == 3) {
      float prev = len - 1 - v.x;
      v.x = len - 1 - v.y;
      v.y = prev;
      v.x += len;
    }
  }
  return v;
}