Cantor's Sets with Processing
Images are generated randomly, but tend to look like this.
1 2 int setHeight = 60; 3 color setColour = color(184 + random(-40, 40), 4 124 + random(-40, 40), 5 124 + random(-40, 40)); 6 int wid = 600; 7 8 void setup() { 9 size(wid, (int)((log(wid) / log(3) + 1) * (setHeight + 5))); 10 background(0); 11 smooth(); 12 13 cantorSet(10, 10, width - 20, setColour); 14 15 save("cantorSet.png"); 16 } 17 18 float rnd(float x) { 19 return x + random(-20, 20); 20 } 21 22 void brushRect(int x, int y, int w, int h) { 23 for (int i = 0; i < h; ++i) { 24 float r = random(3); 25 strokeWeight(r); 26 float downpull = random(h / 4); 27 float shudder = random(-2, 2); 28 line(x + shudder, y + i, x + w - shudder, y + i + downpull); 29 } 30 } 31 32 void cantorSet(int y, int offX, int wid, color col) { 33 if ((y > height - 10) || (wid < 1)) 34 return; 35 36 stroke(col); 37 brushRect(offX, y, wid, setHeight); 38 //fill(col); 39 //rect(offX, y, wid, setHeight); 40 41 color newCol = color(rnd(red(col)), rnd(green(col)), 42 rnd(blue(col))); 43 cantorSet(y + setHeight + 5, offX, wid / 3, newCol); 44 cantorSet(y + setHeight + 5, offX + wid*2/3, wid / 3, newCol); 45 }