class Arm extends Projected { PVector centre; float segLength = random(10)+5; float a1, a2; color colour, overwrite_colour; float da1,da2; ArrayList moves; boolean is_painting, colour_changing; int timer; Arm(int cx, int cy, float a1, float a2, int len, color colour) { centre = new PVector(cx,cy); this.a1 = a1; this.a2 = a2; this.segLength = len; this.a1 = 0; this.a2 = 2 * PI / 4; this.colour = colour; this.colour_changing = false; this.da1 = 0.01; this.da2 = 0.01; is_painting = false; this.timer = 0; overwrite_colour = color(255,255,255); moves = new ArrayList(); } void start_painting() { is_painting = true; } void stop_painting() { is_painting = false; } PVector joint() { return new PVector(centre.x+cos(a1)*segLength,centre.y+sin(a1)*segLength); } PVector end() { PVector p = new PVector(cos(a2)*segLength,sin(a2)*segLength); p.add(joint()); return p; } void arm_draw() { PVector j = trans(this.joint()); PVector c = trans(centre); stroke(0); strokeWeight(4); line(c.x,c.y,j.x,j.y); PVector e = trans(this.end()); stroke(0); strokeWeight(4); line(j.x,j.y,e.x,e.y); } void joggle() { int r,g,b; r = 50+(int)random(20)*10; g = 50+(int)random(20)*10; b = 50+(int)random(20)*10; colour = color(r,g,b); da1 = da1 + (random(4)-2)/100; da2 = da2 + (random(4)-2)/100; } float colour_diff(color c1, color c2) { return (abs(red(c1)-red(c2))+abs(green(c1)-green(c2))+abs(blue(c1)-blue(c1)))/3; } boolean near_colour(color c1, color c2) { return (colour_diff(c1,c2) < 20); } void draw_paint(PGraphics paint, PImage back) { PVector e = trans(this.end()); //if (!near_colour(back.pixels[(int)(e.y*width+e.x)],overwrite_colour)) { return; } paint.beginDraw(); paint.fill(colour); paint.stroke(colour); paint.strokeWeight(1); paint.rect(e.x,e.y,paint_size,paint_size); paint.endDraw(); } PVector calculate_one(float x, float y, float na, float len) { return new PVector(x+cos(na)*len,y+sin(na)*len); } PVector calculate_point(float na1, float na2) { PVector njoint = calculate_one(centre.x,centre.y,na1,segLength); PVector nend = calculate_one(njoint.x,njoint.y,na2,segLength); return nend; } void move_towards(float target_x, float target_y) { PVector target; target = new PVector(target_x,target_y); float[] a1s = { a1+da1,a1+da1,a1-da1,a1-da1,a1+2*da1,a1+2*da1,a1-2*da1,a1-2*da1 }; float[] a2s = { a2+da2,a2-da2,a2+da2,a2-da2,a2+da2,a2-da2,a2+da2,a2-da2 }; PVector[] ps = new PVector[8]; // points float[] ds = new float[8]; // distances for (int i=0;i<8;i++) { ps[i] = calculate_point(a1s[i],a2s[i]); ds[i] = (PVector.sub(target,ps[i])).mag(); } // find the shortest distance float min_v = 999999; int min_ix = -1; for (int i=0;i<8;i++) { if (ds[i] < min_v) { min_ix = i; min_v = ds[i]; } } // shortest is an index min_ix, so change angles a1 = a1s[min_ix]; a2 = a2s[min_ix]; } void timer_update() { timer = timer + 1; int r = (int) random(timer); if (random(timer) > 3000) { timer = 0; if (colour_changing) { joggle(); } } } void update() { move_towards(mouseX,mouseY); timer_update(); } void draw(PGraphics paint,PImage back) { if (is_painting) { draw_paint(paint,back); } arm_draw(); super.draw(); } }