class Lel extends Particle2 { Lel tip[] = new Lel[1]; int ntip; Lel base; float rad, tipAngle; Lel(float x, float y, float r, float ta) { super(x,y,0,0); rad = r; tipAngle = ta; } void display() { for(int i=ntip; --i>=0;) { strokeWeight(max(rad*0.12F, 1.0F)); line(pos.x,pos.y,tip[i].pos.x,tip[i].pos.y); //tip[i].display(); } } void update(float damping) { super.update(damping); // Limit Stretching if(base!=null) { Vector2 bsoff = new Vector2(pos.x - base.pos.x, pos.y - base.pos.y); float bsdist = bsoff.mag(); if(bsdist>rad*1.2) { bsoff.divide(bsdist); bsoff.multiply(rad*1.2); slide(new Vector2(-bsoff.y, bsoff.x)); } else if(bsdist=0;) tip[i].update(damping); } void arrange() { for(int i=ntip; --i>=0;) { float ga = angle()+(ntip==1 ? 0 : lerp(-tipAngle,tipAngle, i/(ntip-1f))); tip[i].pos.set(pos.x+Tbox.rotatedx(tip[i].rad,ga), pos.y+Tbox.rotatedy(tip[i].rad,ga)); tip[i].arrange(); } } void tense(float amount) { //float tipMeanAngle = 0; if(ntip>0) { float myAngle = angle(); for(int i=ntip; --i>=0;) { spring(tip[i].pos, tip[i].rad, amount/ntip); float ga = ntip==1 ? 0 : lerp(-tipAngle,tipAngle, i/(ntip-1f)); tip[i].goalAngle(pos.x,pos.y, ga+myAngle, amount*0.5); //tipMeanAngle += atan2(tip[0].y-y, tip[0].x-x); } //tipMeanAngle /= ntip; } if(base!=null) { spring(base.pos, rad, amount); //if(ntip>0) base.goalAngle(x,y, tipMeanAngle+PI, amount*0.5); } } float angle() { return base==null ? -HALF_PI : atan2(pos.y - base.pos.y, pos.x - base.pos.x); } int iteration() { int iter = 0; Lel testlel = this; while(testlel.base!=null) { testlel = testlel.base; iter++; } return iter; } void plugTip(Lel lel) { boolean plugged = false; for(int i=tip.length; --i>=0;) if(tip[i]==lel) { plugged = true; break; } if(!plugged) { if(ntip==tip.length) { int n = ntip; while(n<=ntip) n *= 2; Lel tmplel[] = new Lel[n]; System.arraycopy(tip,0,tmplel,0,ntip); tip = tmplel; } tip[ntip++] = lel; lel.plugBase(this); } } void plugBase(Lel lel) { base = lel; base.plugTip(this); } }