日常の進捗

主に自分のための,行為とその習慣化の記録

旋回する動き

f:id:takawo:20171021095814g:plain

昨日の続き,というより自由にコーディングしてみる.旋回する動きを数珠つなぎにして前の動きを追従するようにしている.

コード

ArrayList<Tracer> tracers;

Mover mover;
int num = 20;
void setup() {
  size(960, 540);
  colorMode(HSB, 360, 100, 100);
  tracers = new ArrayList<Tracer>();
  for (int i = 0; i < num; i++) {
    Tracer tracer = new Tracer(random(width), random(height));
    tracers.add(tracer);
  }
  mover = new Mover(width/2, height/2);
}

void draw() {
  background(241, 58, 27);

  noFill();
  stroke(27, 52, 96);
  strokeWeight(5);
  beginShape();
  strokeJoin(ROUND);
  vertex(mover.pos.x, mover.pos.y);
  for (int i = 0; i< tracers.size(); i++) {
    vertex(tracers.get(i).pos.x, tracers.get(i).pos.y);
  }
  endShape();

  mover.update();
  mover.draw();

  for (int i = 0; i < num; i++) {
    Tracer tracer = tracers.get(i);
    PVector target;
    if (i == 0) {
      target = mover.pos;
    } else {
      Tracer prev_tracer = tracers.get(i-1);
      target = prev_tracer.pos;
    }
    tracer.seek(target);
    tracer.update();
    tracer.draw();
  }
}


class Tracer {
  PVector pos;
  PVector vel;
  PVector acc;
  float maxSpeed = 3;
  float maxSteer = 0.1;
  float r = 10;
  Tracer(float _x, float _y) {
    pos = new PVector(_x, _y);
    vel = new PVector();
    acc = new PVector();
  }
  void update() {
    vel.add(acc);
    pos.add(vel);
    acc.mult(0);
  }
  void seek(PVector target_pos) {
    PVector desired = PVector.sub(target_pos, pos);
    desired.normalize();
    desired.setMag(maxSpeed);
    PVector steer = PVector.sub(desired, vel);
    steer.limit(maxSteer);
    applyForce(steer);
  }

  void applyForce(PVector force) {
    acc.add(force);
  }

  void draw() {
    noStroke();
    fill(13, 58, 92);
    ellipse(pos.x, pos.y, r*2, r*2);
  }
}

class Mover {
  PVector pos;
  PVector vel;
  PVector acc;
  float r = 15;
  Mover(float _x, float _y) {
    pos = new PVector(_x, _y);
    float degree = random(360);
    float theta = radians(degree);
    float v = 3;
    float vx = cos(theta) * v;
    float vy = sin(theta) * v;
    vel = new PVector(vx, vy);
  }

  void update() {
    pos.add(vel);
    if (pos.x - r < 0 || pos.x + r > width) {
      vel.x *= -1;
    }
    if (pos.y - r < 0 || pos.y + r > height) {
      vel.y *= -1;
    }
  }

  void draw() {
    noStroke();
    fill(351, 66, 83);
    ellipse(pos.x, pos.y, r*2, r*2);
  }
}