Processingで等積な三角形

Processing
スポンサーリンク

はじめに

最近、「美しい幾何学」という本を買ってみてProcessingで参考、応用で作成できそうだなと思ったので作成します。今回は第二章の等積な三角形です。

等積な三角形とは

底辺が等しく、底辺と平行な直線上に高さを与える頂点を持つ全ての三角形は、等しい面積を持つということです。これをProcessingで頂点をずらして9つ表示しました。コードは以下です。

プログラム

頂点をずらす方法はベクトルを使用し、ずれた分だけ方向ベクトルにかけてこれを新たな位置ベクトルとして加えます。これを9つ表示するためクラスを用いて書きました。

PVector[] vec1; //大きい三角形
PVector[] vec2; //小さい三角形
ArrayList<Triangle>  triang = new ArrayList<Triangle>();
int tileCount = 3;

void setup() {
  size(500, 500);
  background(255);
  vec1 = new PVector[3];
  vec2 = new PVector[3];
  
  //図を左から右へ分割する量を増やしながら並べる
  for (int j = 0; j < 3; j++) {
    for (int i = 0; i < 3; i++) {
      float posX = width / tileCount * i;
      float posY = height / tileCount * j;
      if (j == 0) {
        triang.add(new Triangle(posX, posY, i*0.1));
      } else if (j == 1) {
        triang.add(new Triangle(posX, posY, i*0.1+(j+3)*0.1));
      } else if (j == 2) {
        triang.add(new Triangle(posX, posY, i*0.1+(j+6)*0.1));
      }
    }
  }
  noLoop();
}

void draw() {
  background(getCol4());
  
  grid();
  translate(width/tileCount/2, height/tileCount/2);
  for (Triangle triang : triang) {
    triang.ellip();
    triang.dir();
  }
  translate(-width/tileCount/2, -height/tileCount/2);
  powder();
}

void grid() {
  stroke(200, 50, 50);
  for (int j = 1; j < 3; j++) {
    for (int i = 1; i < 3; i++) {
      line(width/tileCount*i, 0, width/tileCount*i, height);
      line(0, height/tileCount*j, width, height/tileCount*j);
    }
  }
}

void powder() {
  for (int i = 0; i < 800000; i++) {
    stroke(random(150), 70);
    strokeWeight(0.6);
    point(random(width), random(height));
  }
}

class Triangle {
  float p_x, p_y, m;

  Triangle(float p_x, float p_y, float m) {
    this.p_x = p_x;
    this.p_y = p_y;
    this.m = m;
  }

  void ellip() {
    fill(getCol4());
    stroke(getCol3());
    ellipse(p_x, p_y, width/4, height/4);
  }

  void dir() {
    pushMatrix();
    translate(p_x, p_y);
    for (int i = 0; i < 3; i++) {
      //正三角形の頂点(cos2nπ/3,sin2nπ/3)より
      vec1[i] = PVector.fromAngle(2 * i * PI / 3);
      vec2[i] = PVector.fromAngle(2 * i * PI / 3);
      vec1[i].mult(width/8);
      vec2[i].mult(width/18);
    }
    
    //大きい三角形の描写
    beginShape();
    for (int i = 0; i < 3; i++) {
      fill(getCol3());
      vertex(vec1[i].x, vec1[i].y);
      vertex(vec1[(i+1)%3].x, vec1[(i+1)%3].y);
    }
    endShape();

    PVector[] dir = new PVector[3];
    PVector[] next = new PVector[3];
    for (int i = 0; i < 3; i++) {
      dir[i] = PVector.sub(vec1[(i+1)%3], vec1[i]); //2頂点間の方向ベクトル
      dir[i].mult(m);//ずれの分を方向ベクトルにかける
      next[i] = PVector.add(vec1[i], dir[i]);//元の頂点の位置ベクトルをずらして新たなベクトルを作る
    }
    
    //小さい三角形とずれた頂点で作る等積な三角形
    beginShape();
    for (int i = 0; i < 3; i++ ) {
      fill(getCol0());
      vertex(vec2[i].x, vec2[i].y);
      vertex(next[i].x, next[i].y);
      vertex(vec2[(i+1)%3].x, vec2[(i+1)%3].y);
    }
    endShape();
  
    //小さい三角形の描写(
    beginShape();
    for (int i = 0; i < 3; i++) {
      fill(getCol4());
      vertex(vec2[i].x, vec2[i].y);
      vertex(vec2[(i+1)%3].x, vec2[(i+1)%3].y);
    }
    endShape();
    popMatrix();
  }
}

int[] colors = {#e63946,#f1faee,#a8dadc,#457b9d,#1d3557};
int getCol0() {
  return colors[0];
}
int getCol1() {
  return colors[1];
}
int getCol2() {
  return colors[2];
}
int getCol3() {
  return colors[3];
}
int getCol4() {
  return colors[4];
}

参考文献

・美しい幾何学

・数学から創るジェネラティブアート

関連記事

Processingおすすめ本
Processingのおすすめ本を紹介します

コメント

タイトルとURLをコピーしました