Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

ペンローズ・タイル

/**
* Penrose Tiling
*
* @author aa_debdeb
* @date 2016/06/29
*/

float e = 400;
color c1, c2;
float phi = (1.0 + sqrt(5)) / 2.0;
ArrayList<Triangle> triangles;

void setup(){
  size(500, 500);
  mousePressed();
}

void draw(){

}

void mousePressed(){
  triangles = new ArrayList<Triangle>();
  for(int i = 0; i < 10; i++){
    float radian1 = radians(i * 36 - 18); 
    float radian2 = radians((i + 1) * 36 - 18);
    PVector[] vertices = new PVector[3];
    vertices[0] = new PVector(0, 0);
    if(i % 2 == 0){
      vertices[1] = new PVector(e * cos(radian1), e * sin(radian1));
      vertices[2] = new PVector(e * cos(radian2), e * sin(radian2));
    } else {
      vertices[2] = new PVector(e * cos(radian1), e * sin(radian1));
      vertices[1] = new PVector(e * cos(radian2), e * sin(radian2));    
    }
    triangles.add(new Triangle(0, vertices));
  }
  for(int i = 0; i < 9; i++){
    ArrayList<Triangle> newTriangles = new ArrayList<Triangle>();
    for(Triangle triangle: triangles){
      ArrayList<Triangle> divided = triangle.divide();
      for(Triangle d: divided){
        newTriangles.add(d);
      }
      triangles = newTriangles;
    }
  }
  c1 = color(random(255), random(255), random(255));
  c2 = color(random(255), random(255), random(255));
  
  background(c1);
  noStroke();
  pushMatrix();
  translate(width / 2, height / 2);
  for(Triangle triangle: triangles){
    triangle.display();
  }
  popMatrix();
}

class Triangle{
  int type;
  PVector[] vertices;
  Triangle(int type, PVector[] vertices){
    this.type = type;
    this.vertices = vertices;
  }
  
  void display(){
    if(type == 0){
      fill(c1);
    } else if(type == 1){
      fill(c2);
    }

    beginShape();
    vertex(vertices[0].x, vertices[0].y);
    vertex(vertices[1].x, vertices[1].y);
    vertex(vertices[2].x, vertices[2].y);    
    endShape();
  }
  
  ArrayList<Triangle> divide(){
    ArrayList<Triangle> divided = new ArrayList<Triangle>();
    if(type == 0){
      PVector p1 = new PVector(lerp(vertices[0].x, vertices[2].x, 1.0 / phi), lerp(vertices[0].y, vertices[2].y, 1.0 / phi));
      PVector[] vs1 = {p1, vertices[0], vertices[1]};
      Triangle t1 = new Triangle(1, vs1);
      divided.add(t1);
      PVector[] vs2 = {vertices[1], vertices[2], p1};
      Triangle t2 = new Triangle(0, vs2);
      divided.add(t2);
    } else if(type == 1){
      PVector p1 = new PVector(lerp(vertices[2].x, vertices[0].x, 1.0 / phi), lerp(vertices[2].y, vertices[0].y, 1.0 / phi));
      PVector p2 = new PVector(lerp(vertices[2].x, vertices[1].x, 1.0 / phi), lerp(vertices[2].y, vertices[1].y, 1.0 / phi));
      PVector[] vs1 = {p2, vertices[0], vertices[1]};
      Triangle t1 = new Triangle(1, vs1);
      divided.add(t1);
      PVector[] vs2 = {p1, p2, vertices[0]};
      Triangle t2 = new Triangle(0, vs2);
      divided.add(t2);
      PVector[] vs3 = {p2, p1, vertices[2]};
      Triangle t3 = new Triangle(0, vs3);
      divided.add(t3);
    }
    return divided;
  }
}