コッホ曲線の拡張

# 代表的なコッホ曲線

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/a20f7182-d27f-4db9-8e4b-a62aa8d371a1.png)

```java
void setup() {
  size(800, 400);
  background(255);
  stroke(0);

  drawKoch(new PVector(50, 300), new PVector(750, 300), 6);
}

void drawKoch(PVector a, PVector b, int n) {
  if (n == 0) {
    line(a.x, a.y, b.x, b.y);
    return;
  }
  // 3等分点
  PVector v = PVector.sub(b, a).div(3);
  PVector p1 = PVector.add(a, v);         // 1/3点
  PVector p2 = PVector.add(a, v.copy().mult(2)); // 2/3点

  // 正三角形の頂点
  float th = atan2(b.y - a.y, b.x - a.x) - PI/3;
  float len = v.mag();
  PVector peak = new PVector(
    p1.x + cos(th)*len,
    p1.y + sin(th)*len
  );

  drawKoch(a, p1, n-1);
  drawKoch(p1, peak, n-1);
  drawKoch(peak, p2, n-1);
  drawKoch(p2, b, n-1);
}
```

# 正三角形を正方形へ変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/59c60fce-5749-49e7-b5c2-1c5d0bf46b8b.png)

```java
void setup() {
  size(800, 400);
  background(255);
  stroke(0);

  drawKochSquare(new PVector(50, 360), new PVector(750, 360), 6);
}

void drawKochSquare(PVector a, PVector b, int n) {
  if (n == 0) {
    line(a.x, a.y, b.x, b.y);
    return;
  }
  PVector v = PVector.sub(b, a).div(3);
  PVector p = PVector.add(a, v);
  PVector q = PVector.add(a, v.copy().mult(2));
  float px = p.x, py = p.y, qx = q.x, qy = q.y;
  float dx = qx - px, dy = qy - py;
  float ox = dy, oy = -dx;
  PVector up = new PVector(px + ox, py + oy);
  PVector right = new PVector(qx + ox, qy + oy);
  drawKochSquare(a, p, n-1);
  drawKochSquare(p, up, n-1);
  drawKochSquare(up, right, n-1);
  drawKochSquare(right, q, n-1);
  drawKochSquare(q, b, n-1);
}
```

# 平面から立体へ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/d6ce4cb3-f09a-4a17-8516-0efdd05b7f77.png)

```java
//import nervoussystem.obj.*;

float size = 600;
int depth = 4;

void setup() {
  size(600, 500, P3D);
  fill(255);
  stroke(50,20);
}

void draw() {
  background(255);
  lights();
  //beginRecord("nervoussystem.obj.OBJExport", "FractalSquare.obj");
  translate(width/2, height/2, -300);
  rotateX(PI/3);
  rotateZ(PI/3);
  drawFractalSquare(size, depth);
  //endRecord();exit();
}

void drawFractalSquare(float size, int depth) {
  if (depth == 0) {
    // xy平面に正方形
    beginShape();
    vertex(-size/2, -size/2, 0);
    vertex( size/2, -size/2, 0);
    vertex( size/2,  size/2, 0);
    vertex(-size/2,  size/2, 0);
    endShape(CLOSE);
    return;
  }
  float sub = size / 3;
  for (int i=0; i<3; i++) {
    for (int j=0; j<3; j++) {
      pushMatrix();
      translate((i-1)*sub, (j-1)*sub, 0);
      if (i==1 && j==1) {// 中央：押し出し
        pushMatrix();
        translate(0, 0, size/3);
        drawFractalSquare(sub, depth-1);
        popMatrix();
        for (int k=0; k<4; k++) {// 側面（4方向, ズレ補正あり）
          pushMatrix();
          rotateZ(HALF_PI*k);
          translate(0, -sub/2, sub/2); // 中心合わせる
          rotateX(HALF_PI);
          drawFractalSquare(sub, depth-1);
          popMatrix();
        }
      } else {
        drawFractalSquare(sub, depth-1);
      }
      popMatrix();
    }
  }
}
```

# 立方体６面に配置し3Dプリント
![IMG_9948.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/d8e8a8f2-9b79-403d-a9af-6479b0000ef0.jpeg)

# 参考

https://en.m.wikipedia.org/wiki/Koch_snowflake