public class Paint { ArrayList lines; ArrayList dots; Point last; int total; float spacing, inv_spacing; Paint(float spacing, int total){ lines = new ArrayList(); dots = new ArrayList(); last = null; this.spacing = spacing; this.total = total; inv_spacing = 1.0 / spacing; } void createLine(Point a, Point b, float speed){ lines.add(new Line(a, b, speed)); } /* Adds dots inbetween dots that are too far apart */ void interpolate(Point a, Point b) { Line line = new Line(a, b, 1); // the number of segments we will divide the gap into int denominator = (int)(line.length * inv_spacing); // the distance between each new dot float step = line.length / denominator; for(float n = step; n < line.length; n += step) { // hack to deal with flash's bullshit floating point math if(line.length - n < step * 0.5) break; dots.add(new Point(a.x + line.dx * n, a.y + line.dy * n)); } } /* Returns true if (x0,y0) is less than len from (x1,y1) */ boolean proximity(float x0, float y0, float x1, float y1, float length){ return (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) <= length * length; } void main() { int i, j; if(mouse_count == frame_count) { clear(); } // painting routine if(mouse_pressed){ float x = mouseX; float y = mouseY; Point next = null; if(last != null){ if(!proximity(x, y, last.x, last.y, spacing)){ next = new Point(x, y); } } else { last = new Point(x, y); dots.add(last); } if(next != null) { float distance = Point.dist(last, next); if(!proximity(last.x, last.y, next.x, next.y, spacing * 2)) { interpolate(last, next); } dots.add(next); float speed = 1.0 / distance; while(dots.size() > 1) { last = (Point)dots.get(1); createLine((Point)dots.remove(0), last, speed); } while(lines.size() >= total) lines.remove(0); } } draw(); } /* clears the paint from the screen and memory */ void clear() { lines = new ArrayList(); dots = new ArrayList(); last = null; } void draw(){ /* // strokeWeight method // handled badly by the OPENGL renderer for(int i = 0; i < lines.size(); i++){ Line temp = (Line)lines.get(i); temp.draw(g); //ellipse(temp.a.x, temp.a.y, 5, 5); }*/ /* noFill(); strokeWeight(5); if(p.size()> 0){ beginShape(); Line temp = (Line)p.get(0); curveVertex(temp.a.x, temp.a.y); for(int i = 0; i < p.size(); i++){ stroke(i * 10); temp = (Line)p.get(i); curveVertex(temp.b.x, temp.b.y); } endShape(); } */ /* // triangle strip method // needs polish if(lines.size() > 1){ fill(255); noStroke(); //noFill(); //stroke(255); beginShape(TRIANGLE_STRIP); Line temp = (Line)lines.get(0); vertex(temp.a.x, temp.a.y); vertex(temp.b.x, temp.b.y); for(int i = 1; i < lines.size()-1; i++){ temp = (Line)lines.get(i); float wide = temp.speed * 10; vertex(temp.a.x + temp.rx * wide, temp.a.y + temp.ry * wide); vertex(temp.b.x + temp.lx * wide, temp.b.y + temp.ly * wide); } temp = (Line)lines.get(lines.size()-1); vertex(temp.a.x, temp.a.y); vertex(temp.b.x, temp.b.y); endShape(); }*/ // curve method // slow, and generates overlap problems /*if(lines.size() > 1){ fill(255); noStroke(); //noFill(); // stroke(255); beginShape(POLYGON); Line temp; for(int i = 0; i < lines.size(); i++){ temp = (Line)lines.get(i); float wide = temp.speed * 10; curveVertex(temp.a.x + temp.lx * wide, temp.a.y + temp.ly * wide); } for(int i = lines.size()-1; i > -1; i--){ temp = (Line)lines.get(i); float wide = temp.speed * 10; curveVertex(temp.b.x + temp.rx * wide, temp.b.y + temp.ry * wide); } endShape(); }*/ // polygon method if(lines.size() > 2){ float radius = 40; fill(255); noStroke(); //noFill(); // stroke(255); beginShape(); Line temp = (Line)lines.get(0); float dx, dy; vertex(temp.a.x, temp.a.y); // we're interpolating between the side normals of the lines at each joint dx = temp.lx; dy = temp.ly; for(int i = 1; i < lines.size(); i++){ temp = (Line)lines.get(i); float wide = temp.speed * radius; vertex(temp.a.x + (temp.lx + dx) * wide, temp.a.y + (temp.ly + dy) * wide); dx = temp.lx; dy = temp.ly; } vertex(temp.b.x, temp.b.y); dx = temp.rx; dy = temp.ry; for(int i = lines.size()-2; i > 0; i--){ temp = (Line)lines.get(i); float wide = temp.speed * radius; vertex(temp.a.x + (temp.rx + dx) * wide, temp.a.y + (temp.ry + dy) * wide); dx = temp.rx; dy = temp.ry; } temp = (Line)lines.get(0); vertex(temp.a.x, temp.a.y); endShape(); } } }