日常の進捗

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

Mod:Coding Challenge #2: Menger Sponge Fractal

コードを写しながら解説を聴く感じ。x,y,zで-1から1の範囲で繰り返して、それを元に座標計算をする流れは新鮮だった。内容としては完成したものを自分なりの書き方に書き換えた他、座標ごとに個別で回転や世代のループ、視点移動させるなどしている。

ArrayList<Box> boxes;
int gen =0;
void setup() {
  size(960, 540, P3D);
  colorMode(HSB, 360, 100, 100, 100);
  Box b = new Box(0, 0, 0, 300);
  boxes = new ArrayList<Box>();
  boxes.add(b);
}

void mousePressed() {
  nextGen();
}


void draw() {
  lights();
  background(180, 30, 20);
  translate(width/2, height/2, sin(frameCount*0.01)*250-250);
  rotateX(frameCount*0.01);
  rotateY(frameCount*0.01*0.5);
  rotateZ(frameCount*0.01*0.2);
  for (Box b : boxes) {
    b.draw();
  }
  if (frameCount%100 == 0) {
    nextGen();
  }
}

void nextGen() {
  ArrayList<Box> next = new ArrayList<Box>();
  for (Box b : boxes) {
    ArrayList<Box> newBoxes = b.generate();
    next.addAll(newBoxes);
  }
  boxes = next;
  gen++;
  if (gen > 3) {
    boxes.clear();
    Box b = new Box(0, 0, 0, 300);
    boxes.add(b);
    gen = 0;
  }
}

class Box {
  PVector pos;
  float r;
  Box(float x, float y, float z, float _r) {
    pos = new PVector(x, y, z);
    r = _r;
  }


  ArrayList<Box> generate() {
    ArrayList<Box> boxes = new ArrayList<Box>();
    for (int z = -1; z < 2; z = z+1) {
      for (int y = -1; y < 2; y = y+1) {
        for (int x = -1; x < 2; x = x+1) {
          float newR = r / 3;
          int sum = abs(x) + abs(y) + abs(z);
          if (sum > 1) {
            Box b = new Box(pos.x+x*newR, pos.y+y*newR, pos.z+z*newR, newR);
            boxes.add(b);
          }
        }
      }
    }
    return boxes;
  }

  void draw() {
    pushMatrix();
    translate(pos.x, pos.y, pos.z);
    fill(180+0.1*(pos.x+pos.y+pos.z+frameCount)%360, 80, 100);
    noStroke();
    rotateX((pos.x+frameCount)*0.001);
    rotateY((pos.y+frameCount)*0.001*0.5);
    rotateZ((pos.z+frameCount)*0.001*0.2);
    box(r);
    popMatrix();
  }
}