Generative art experiment 4: colourful roots
February 26, 2013
It’s been a while since I’ve posted about anything interesting that I’ve made in Processing. Time to put an end to that! Allow me to present “colourful roots”. It started off as a simple particle system with the usual fade effect, but when I let the particle shrink and stay fully opaque, I was delighted to see what it looked like!
The processing code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
// canvas colour int background_color = color(70, 70, 70); // particle colours color[] colors = { color (227, 211, 31), // yellow color (227, 31, 123), // pink color (31, 188, 227) // blue }; // colour of the stroke around the particles color stroke_color = color(0, 70); // black, 70% alpha // should the mouse draw particles when moved? Boolean INTERACTIVE = true; // should the canvas be cleared on each particle iteration Boolean CLEAR = false; //-----------------------------------------------------------------// //-----------------------------------------------------------------// //-----------------------------------------------------------------// //-----------------------------------------------------------------// ArrayList particles; // reset on mouse click void mouseClicked () { setup(); mouseMoved(); } // save on press spacebar void keyPressed () { if (keyCode == RETURN || keyCode == ENTER) { save("Colourful entrails " + year() + "-" + month() + "-" + day() + " " + hour() + ":" + minute() + ":" + second() + ".png"); } } // add particles on mouse move void mouseMoved () { if (!INTERACTIVE) return; int count = int(random(2, 5)); while(count-- > 0) { addParticle(new PVector(mouseX, mouseY)); } } void setup() { size(800, 400, P2D); blendMode(ADD); stroke(stroke_color); background(background_color); particles = new ArrayList(); // create a particle which'll go around making particles if it's not interactive if (!INTERACTIVE) { Particle generator = new Particle(new PVector(width/2, height/2)); generator.size = 10000; while(generator.isAlive()) { int count = int(random(2,5)); generator.update(); while (count-- > 0) { addParticle(generator.position); } } } } // add a new particle to the particles arraylist with specified position void addParticle (PVector position) { // clone the vector PVector position_clone = new PVector(position.x, position.y); particles.add(new Particle(position_clone)); } void draw() { // keep track of dead particles - they'll be removed after the loop ArrayList dead = new ArrayList(); if (CLEAR) { fill(background_color); rect(0, 0, width, height); } // go through each of the particles and update/draw ListIterator it = particles.listIterator(); while (it.hasNext()) { Particle particle = (Particle) it.next(); // only draw if it's alive if (particle.isAlive()) { particle.update(); particle.draw(); } else { // otherwise add to dead list dead.add(particle); } } // remove all dead particles particles.removeAll(dead); } // a tad messy, building it up as i go along class Particle { PVector position; PVector velocity; PVector force; float size; color c; int life; Particle (PVector p) { life = 0; position = p; size = random(30, 50); velocity = new PVector(random(2, 5), 0); rotate2D(velocity, random(0, TWO_PI)); c = colors[int(random(colors.length))]; force = new PVector(0, 1); } void update () { life++; if (life == 20) { velocity.mult(1.1); } if (life < 20) { size *= 0.99; } else { size *= 0.95; } position.add(velocity); velocity.rotate(random(-QUARTER_PI, QUARTER_PI)); } void draw () { pushMatrix(); translate(position.x, position.y); fill (c); ellipse(0, 0, size, size); popMatrix(); } Boolean isAlive() { return size >= 1; } } void rotate2D(PVector v, float theta) { float xTemp = v.x; v.x = v.x*cos(theta) - v.y*sin(theta); v.y = xTemp*sin(theta) + v.y*cos(theta); } |