class Link { static final float LINK_SEPARATION = 5; static final int RELAXATIONS = 1; static final float GRAVITY = 100; static final float DAMPING = 0.02; float x, y; // Current pos float px, py; // Previous pos float fx, fy; // Force float mass; Link prev_link; Link(Link prev_link, float x, float y) { this.x = px = x; this.y = py = y; fx = fy = 0; mass = 0.001; this.prev_link = prev_link; } void relax() { for(int i = 0; i < RELAXATIONS; i++) { if(prev_link != null) { float separation = dist(prev_link.x, prev_link.y, x, y); float delta_x = prev_link.x - x; float delta_y = prev_link.y - y; float masses = 1.0/prev_link.mass + 1.0/mass; float diff = (separation-LINK_SEPARATION)/separation/masses; x += diff*delta_x*(1.0/mass); y += diff*delta_y*(1.0/mass); prev_link.x -= diff*delta_x*(1.0/prev_link.mass); prev_link.y -= diff*delta_y*(1.0/prev_link.mass); } } } void update(float dt) { // Apply grav fy += GRAVITY * mass; // Damping fx -= (x-px)*DAMPING; fy -= (y-py)*DAMPING; // Verlet float tmp_x = x; float tmp_y = y; x = 2*x - px + (fx/mass)*dt*dt; y = 2*y - py + (fy/mass)*dt*dt; px = tmp_x; py = tmp_y; fx = fy = 0; } void draw() { // Fill if(prev_link != null) { noStroke(); fill(255); beginShape(); vertex(x, y); vertex(px, py); vertex(prev_link.px, prev_link.py); vertex(prev_link.x, prev_link.y); endShape(CLOSE); } // Grid /*stroke(255); if(prev_link != null) line(x, y, prev_link.x, prev_link.y); line(x, y, px, py);*/ } }