読者です 読者をやめる 読者になる 読者になる

30 min. Processing

毎日30分、Processingで何かを作る

ゴムの紐

物理
/**
* elastic string
*
* @author aa_debdeb
* @date 2017/01/03
*/

int FPS = 30;
int NODE_NUM = 100;
float GRAVITY = 1.0; 
float K_SPRING = 10.0;
float K_DAMPING = 10.0;
PVector[] locs;
PVector[] vels;
float l;

void setup(){
  size(640, 640);
  frameRate(FPS);
  noFill();
  stroke(#F8FAD4);
  strokeWeight(4);
  locs = new PVector[NODE_NUM];
  vels = new PVector[NODE_NUM];
  float startW = 120;
  float endW = 520;
  for(int i = 0; i < NODE_NUM; i++){
    float w = map(i, 0, NODE_NUM - 1, startW, endW);
    float h = height / 4;
    locs[i] = new PVector(w, h);
    vels[i] = new PVector(0, 0);
  }
  l = (endW - startW) / (NODE_NUM - 1);
}

void draw(){
  background(#007FB1);
  beginShape();
  for(int i = 0; i < NODE_NUM; i++){
    vertex(locs[i].x, locs[i].y);
  }
  endShape();
    
  PVector[] nextVels = new PVector[NODE_NUM];
  for(int i = 1; i < NODE_NUM - 1; i++){
    PVector springForceLeft = getSpringForce(i, i - 1);
    PVector springForceRight = getSpringForce(i, i + 1);
    PVector dampingForceLeft = getDampingForce(i, i - 1);
    PVector dampingForceRight = getDampingForce(i, i + 1);
    PVector gravityForce = getGravityForce(i);
    PVector force = new PVector(0, 0);
    force.add(springForceLeft);
    force.add(springForceRight);
    force.add(dampingForceRight);
    force.add(dampingForceLeft);
    force.add(gravityForce);
    PVector acc = PVector.mult(force, 1.0 / FPS);
    PVector nextVel = PVector.add(vels[i], acc);
    nextVels[i] = nextVel;
  }
  for(int i = 1; i < NODE_NUM - 1; i++){
    vels[i] = nextVels[i];
    locs[i].add(vels[i]);
  }
}

PVector getSpringForce(int i, int j){
  PVector locDiff = PVector.sub(locs[j], locs[i]);
  PVector force = PVector.mult(locDiff, K_SPRING * (locDiff.mag() - l) / locDiff.mag());
  if(j == 0 || j == NODE_NUM - 1){
    force.mult(0.5);
  }
  return force;
}

PVector getDampingForce(int i, int j){
  PVector velDiff = PVector.sub(vels[j], vels[i]);
  PVector force = PVector.mult(velDiff, K_DAMPING);
  if(j == 0 || j == NODE_NUM - 1){
    force.mult(0.5);
  }
  return force;
}

PVector getGravityForce(int i){
  return new PVector(0, GRAVITY);
}
f:id:aa_debdeb:20161229161557j:plain