日常の進捗

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

Mod:Coding Challenge #81.1: Circle Morphing - Part 1

円から三角形のモーフィング,パート1.円周上の点,三角形の辺上の点をそれぞれ配列として保存して,その間を動く点を描画する.

コード

ArrayList<PVector> circlePath = new ArrayList<PVector>();
ArrayList<PVector> trianglePath = new ArrayList<PVector>();
int n = (int)random(3,10);
int spacing = 1;
float theta = 0;

void setup() {
  size(600, 600);
  colorMode(HSB, 360, 100, 100);
  setN();
}

void draw() {
  background(220, 20, 40);
  translate(width / 2, height / 2 + 0);
  rotate(radians(360/n/4));
  stroke(0, 0, 100);
  strokeWeight(8);
  strokeJoin(ROUND);
    noFill();
  float amt = map(sin(theta), -1, 1, 0, 1);
  if (amt < 0.01) {
   do{
    n = (int)random(3, 10);
    }while(n == 7)
    circlePath.clear();
    trianglePath.clear();
    setN();
  }
  theta += radians(4);
  beginShape();
  for (int i = 0; i < circlePath.size(); i++) {
    PVector cv = circlePath.get(i);
    PVector tv = trianglePath.get(i);
    float x = lerp(cv.x, tv.x, amt);
    float y = lerp(cv.y, tv.y, amt);
    vertex(x, y);
  }
  endShape(CLOSE);
}

void setN() {
  float radius = sqrt(sq(width/2)+sq(height/2))*0.5;
  float startA = 0;
  float endA = 360/n;
  PVector start = polarToCartesian(radius, startA); 
  PVector end = polarToCartesian(radius, endA);
  for (float angle = startA; angle < 360; angle += spacing) {
    PVector cv = polarToCartesian(radius, angle);
    circlePath.add(cv);
    float amt = (angle % (360/n)) / (endA - startA);
    PVector tv = PVector.lerp(start, end, amt);
    trianglePath.add(tv);

    if ((angle + spacing) % (360/n) == 0) {
      startA = startA + 360/n;
      endA = endA + 360/n;
      start = polarToCartesian(radius, startA);
      end = polarToCartesian(radius, endA);
    }
  }
}

PVector polarToCartesian(float radius, float angle) {
  return new PVector(radius*cos(radians(angle)), radius*sin(radians(angle)));
}

リファレンス