import traer.physics.*; import com.nootropic.processing.layers.*; AppletLayers layers; boolean newClick = false; PImage img; void setup() { size(512, 512, JAVA2D); frameRate(24); layers = new AppletLayers(this); layers.addLayer(new SparksLayer(this)); img = loadImage("marylin.jpg"); img.loadPixels(); img = glitcH(img); img.updatePixels(); image(img, 0, 0); } PImage glitcH(PImage img) { img.save("data/glitch-out.jpg"); byte raw[] = loadBytes("glitch-out.jpg"); int i = 0; // skip the jpeg header while (! (raw[i] == (byte) 0xff && raw[i+1] == (byte) 0x02) && i < raw.length -1) { i++; } // modify the remaining bytes while (i < raw.length) { if (raw[i] == 99) { raw[i]++; } i++; } saveBytes("data/glitch-out.jpg", raw); img = loadImage("glitch-out.jpg"); return img; } void paint(java.awt.Graphics g) { if (layers != null) { layers.paint(this); } else { super.paint(g); } } void draw() { if (mousePressed) { noCursor(); smooth(); stroke(0); strokeWeight(random(2, 4)); if (!newClick) { line(mouseX, mouseY, pmouseX, pmouseY); } newClick = false; int size = (int)random(5, 10); int dx = (int)random(-5, 5); int dy = (int)random(-5, 5); copy(mouseX - size/2, mouseY - size/2, size, size, mouseX+dx-(size/2), mouseY+dy-(size/2), size, size); } else { cursor(CROSS); } } void mousePressed() { newClick = true; } void keyPressed() { if (key == 's') { saveFrame("draw-######.png"); // return img; } } class SparksLayer extends Layer { float gravity = 5.0f; float drag = 0.5f; float sparkMass = 10.0f; int sparkColor = color(0xff, 0xff, 0xff); float maxV = 8; float lifetimeMin = 5; float lifetimeMax = 25; ParticleSystem system; ArrayList sparks = new ArrayList(); int maxPositions = 20; int nTicks = 2; SparksLayer(PApplet parent) { super(parent); } void setup() { system = new ParticleSystem(gravity, drag); background(0); } void draw() { background(0, 0); smooth(); if (mousePressed) { float nSparks = random(1, 20); for (int i = 0; i < nSparks; i++) { makeSpark(); } } advanceTime(nTicks); ListIterator it = sparks.listIterator(); setVisible(false); while (it.hasNext()) { Spark spark = (Spark) it.next(); if (spark.lifetime < spark.particle.age()) { system.removeParticle(spark.particle); it.remove(); } else { setVisible(true); drawSpark(spark); } } } void advanceTime(int n) { for (int i = 0; i < n; i++) { system.tick(); ListIterator it = sparks.listIterator(); while (it.hasNext()) { Spark spark = (Spark) it.next(); ArrayList positions = spark.pastPositions; Vector3D position = spark.particle.position(); positions.add(new Vector3D(position.x(), position.y(), position.z())); } } ListIterator it = sparks.listIterator(); while (it.hasNext()) { Spark spark = (Spark) it.next(); int nRemove = spark.pastPositions.size() - maxPositions; ListIterator positions = spark.pastPositions.listIterator(); for (int i = 0; i < nRemove; i++) { positions.next(); positions.remove(); } } } void drawSpark(Spark spark) { stroke(sparkColor); int index = spark.pastPositions.size() - 1; Vector3D p1 = (Vector3D) spark.pastPositions.get(index--); int indexLimit = index - spark.tailLength; if (indexLimit < 0) { indexLimit = 0; } int loopCount = 0; while (index > indexLimit) { Vector3D p2 = (Vector3D) spark.pastPositions.get(index); if (loopCount < 2) { strokeWeight(2); } else { strokeWeight(1); } line(p1.x(), p1.y(), p2.x(), p2.y()); p1 = p2; loopCount++; index--; } } void makeSpark() { Particle p = system.makeParticle(sparkMass, mouseX, mouseY, 0); float xv = random(-maxV, maxV); float yv = random(-maxV, maxV); p.velocity().set(xv, yv, 0); sparks.add(new Spark(p)); } class Spark { Particle particle; float lifetime; int tailLength; ArrayList pastPositions = new ArrayList(); Spark(Particle p) { this.particle = p; this.lifetime = random(lifetimeMin, lifetimeMax); this.tailLength = (int)random(3, 6); } } }