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; }