21. Oktober 2011
Floral Recursion
I modified the original tree by replacing the black lines with brown bezier curves, and drawing flowers with a floral pattern. When I realized that the background doesn't have to be erased every time the draw() function is called, the tool turned into a floral drawing tool of sorts. By clicking and dragging the mouse from one point to another, it will either draw a bush with flowers or just the flowers (the user can decided the level of recursion).boolean paint = true; boolean repaint = false; int depth = 5; int[] xCoords = new int[10]; int[] yCoords = new int[10]; float[] treeScale = new float[10]; int[] branchCount = new int[10]; PGraphics pg; float[] mousePosition = {0, 0, 0, 0}; float[] newCoords = {0, 0}; int frameCounter = 0; boolean noline = false; int factor = 10; //is divided by 10 void setup() { size(800,800); // def. fenstergroesse randomSeed(millis()); // seed random smooth(); // aktiviere antialiasing strokeWeight(7); // linienbreite stroke(#833E09,100); pg = createGraphics(width, height, P2D); //frameRate(1); noLoop(); pg.beginDraw(); pg.background(255); pg.endDraw(); image(pg, 0, 0); } void draw() { /*pushMatrix(); translate((width / 2), height - 20); wurzel(depth, 1); popMatrix();*/ if(repaint == true) { pushMatrix(); translate(mousePosition[0], mousePosition[1]); wurzel(depth, depth); popMatrix(); } } void mousePressed() { pushMatrix(); translate(mousePosition[0], mousePosition[1]); mousePosition[0] = mouseX; mousePosition[1] = mouseY; popMatrix(); } void mouseReleased() { redraw(); repaint = true; pushMatrix(); translate(mousePosition[0], mousePosition[1]); mousePosition[2] = mouseX; mousePosition[3] = mouseY; popMatrix(); getAngle(); } void keyPressed() { if((int)keyCode >= 49 && (int)keyCode <= 57) { depth = (int)keyCode - 48; } else if (keyCode == 83) { saveFrame("data/frame-####.png"); println("saved"); } else if (keyCode == 8) { background(255); repaint = false; redraw(); } else { if(noline == false) noline = true; else noline = false; } } // funktion void wurzel(int tiefe, int tiefeTotal) { if(tiefe <= 0) // teste ob das ende erreicht worden ist { // zeichen blueten pushStyle(); int clr = (int)random(0,255); scale((float)clr % 20 / 10 + 0.1); stroke(clr, clr * 2 % 255,0,190); strokeJoin(BEVEL); strokeWeight(2); fill(clr, clr * 2 % 255,0,50); //ellipse(0,0,50,50); /*beginShape(); arc(0, 0, 20, 50, 0, 180); arc(0, 0, 20, 50, 180, 360); endShape();*/ for (int i = 0; i <= 7; i++) { rotate(radians(45 * i)); beginShape(); vertex(0, 0); bezierVertex(5, 15, 5, 15, 20, 20); bezierVertex(35, 10, 35, 10, 40, 0); bezierVertex(20, -10, 20, -10, 0, 0); endShape(CLOSE); } popStyle(); //paint = false; return; } // zeichne zweige int x; int y; int count; float localScale; if (paint == true) { count = (int)random(1,8); branchCount[tiefe] = count; } else { count = branchCount[tiefe]; } for(int i = 0; i < count;i++) { if(paint == true) { x = (int)random(newCoords[0] / tiefeTotal - 100, newCoords[0] / tiefeTotal + 100); y = -(int)random(newCoords[1] / tiefeTotal - 100, newCoords[1] / tiefeTotal + 100); xCoords[tiefe] = x; yCoords[tiefe] = y; }else{ x = xCoords[tiefe]; y = yCoords[tiefe]; } //int distance = (int)dist(mouseX, mouseY, x, y); int distance = 0; noFill(); if(noline == false) bezier(0 + distance * 0.1 ,0 + distance * 0.1, x/4, y/4*3, x/4*3, y/4 , x + distance * 0.1, y + distance * 0.1); pushMatrix(); translate(x,y); if(paint == true) { localScale = random(.3,.95); treeScale[tiefe] = localScale; } else { localScale = treeScale[tiefe]; } scale(localScale); wurzel(tiefe-1, tiefeTotal); popMatrix(); } } void getAngle() { newCoords[0] = mousePosition[2] - mousePosition[0];<a href="http://blogs.iad.zhdk.ch/codingspace2011/files/2011/10/frame-1881.png"><img src="http://blogs.iad.zhdk.ch/codingspace2011/files/2011/10/frame-1881-150x150.png" alt="" title="frame-1881" width="150" height="150" class="alignleft size-thumbnail wp-image-1185" /></a> newCoords[1] = mousePosition[1] - mousePosition[3]; }
Circular recursion (not literally)
Here, I took a more experimental approach. Starting from black and white, I wanted to create circles around circles, around cirlces, in different sizes and amounts. After managing to position circles around cirlces (from picture 2 onward), I started to experiment with colors and user interaction. The final version includes user interaction: if the user moves the mouse towards the middle, the pattern contracts, and vice versa. The patterns created through mouse movement can be saved as single images (by pressing the "s" key).
import peasy.*; int randomizer = 0; int[] size = {900, 900}; float mouseFactor = 1; int eDepth = 4; int eSize = 200; int bgColorR = 0; int bgColorB = 0; int bgColorG = 0; int mode = 0; fractalEllipse ellips = new fractalEllipse(eDepth, eDepth, eSize); boolean repaint = true; void setup () { size(size[0], size[1]); smooth(); randomSeed(millis()); noFill(); noStroke(); frameRate(60); //noLoop(); } void draw() { if(repaint == true) { if(mode == 1) { bgColorR = (int)random(0, 255); bgColorG = (int)random(0, 255); bgColorB = (int)random(0, 255); } else { bgColorR = bgColorG = bgColorB = 0; } /*for(int i = 0; i < size[0]; i++) { if(i > 360) break; fill(i); ellipse(0, 0, size[0] - i * 2.3, size[1] - i * 2.3); }*/ repaint = false; } background(bgColorR, bgColorG, bgColorB); translate(size[0] / 2, size[1] / 2); ellips.paintFractal(mouseFactor); } void keyPressed() { if (keyCode == 83) { saveFrame("data/frame-####.png"); println("saved"); } else if (keyCode == 8) { //background(255); repaint = true; //redraw(); } } public class fractalEllipse { ArrayList ellipses = new ArrayList(); ArrayList ellipseSizes = new ArrayList(); int x, y, z, size, angle, depth, totalDepth, r, g, b; float eScale; public fractalEllipse(int currentDepth, int totalDepth, int elSize) { if(currentDepth == totalDepth) { this.r = (int)random(0, 255); this.g = (int)random(0, 255); this.b = (int)random(0, 255); } elSize = floor(elSize + mouseFactor); println(mouseFactor); this.depth = currentDepth; this.totalDepth = totalDepth; if(currentDepth > 0) { this.eScale = random(0.3, 0.75); this.angle = (int)random(1, 20); this.x = elSize; this.y = elSize; this.z = elSize; for (int i = 0; i < angle; i++) { //int elSize = (int)random(25, 75); this.ellipseSizes.add(elSize); fractalEllipse newEllipse = new fractalEllipse(currentDepth -1, totalDepth, elSize); this.ellipses.add(newEllipse); } } else { return; } } public void paintFractal(float mouseFactor) { if(this.depth > 0) { this.x += mouseFactor; this.y += mouseFactor; scale(this.eScale); for (int i = 0; i < angle; i++) { pushMatrix(); strokeWeight(this.depth); stroke((this.r + this.depth * 10 + this.x) % 200 + 55, (this.g + this.angle * i - this.depth * 10 + this.x) % 200 + 55, (this.b + this.angle * i + this.depth * 20 + this.x) % 200 + 55, 255 - (this.totalDepth - this.depth)); rotate(radians(360 / this.angle * i)); translate(this.x, this.y); ellipse(0, 0 , (Integer)ellipseSizes.get(i), (Integer)ellipseSizes.get(i)); fractalEllipse nextEllipse = (fractalEllipse)ellipses.get(i); nextEllipse.paintFractal(mouseFactor); popMatrix(); } } } } void mouseMoved() { int distance = (int)dist(size[0] / 2, size[1] / 2, mouseX, mouseY); mouseFactor = map(distance, 0, size[0] / 2, -eSize / 100, eSize / 100); println(distance); } void mouseClicked() { repaint = true; ellips = new fractalEllipse(eDepth, eDepth, eSize); }