ここでは、正三角形と正六角形によるタイリング(2通りあるうちの1つで「正三角形と正六角形②」とします)を再現してみました。なお、今回のタイリングを作成するにあたって、書籍「アートで魅せる数学の世界」の「2種類以上の正多角形によるタイリング」(p.94)を参考にしました。

正三角形と正六角形②

タイリング〈正三角形と正六角形②〉は以下のような図形になります。

正三角形と正六角形②

以下で、このタイリング〈正三角形と正六角形②〉の描き方について解説していきます。

正三角形と正六角形②の描き方

対称性について

まず、このタイリング〈正三角形と正六角形②〉の対称性について考えます。

正三角形と正六角形②の対称性

上図のように、タイリングのパターンをじっくり見ていくと、上図の赤丸の周りの180°回転、青丸の周りの120°回転、および緑丸の周りの60°回転に対して図形は回転対称になっていることが分かります。また、黒色の点を格子としてみると、近接する3つの黒色の点同士が正三角形を形作っていることから、黒色の点は三角格子になっていることが分かります。これらをまとめると、タイリング〈正三角形と正六角形②〉は、壁紙群P6の対称性を持つことが分かります。

アイソヘドラルタイリングの観点でみると、IH11(P6)IH21(P6)IH34(P6)IH90(P6)のいずれにも分類することができますが、今回は基本図形が一番細かくなるIH21(P6)で再現しました。

基本図形の準備

タイリング〈正三角形と正六角形②〉に現れる正三角形や正六角形の一辺の長さを\(1\)とすると、タイリング〈正三角形と正六角形②〉の基本図形は、辺の長さが\(1\)となる正三角形を2つと、底辺の長さが\(1\)で頂角が120°となる二等辺三角形を組み合わせたものになります(下図参照)。

正三角形と正六角形②の基本図形

三角格子の準備

また、正方格子は、上図の基本図形で示したように、1つの正三角形の頂点ともう1つの正三角形の辺の中点が近接する三角格子点となるように準備します。

壁紙群P6の対称性に合わせて並べる

ここまで準備ができたら、あとは壁紙群P6の対称性に合わせて基本図形を並べていくことでタイリング〈正三角形と正六角形②〉を作成することができます。

ソースコード

今回再現したタイリング〈正三角形と正六角形②〉のプログラムのソースコードを示しておきます。

PVector[][] lattice; // 格子点ベクトル
PShape tile; // タイル
PVector[] base = new PVector[2]; // 格子を張るベクトル
int col_num = 8; // 描画するタイルの列の数
float scalar; // タイルの辺の長さ

void setup(){

  size(1000, 1000, P2D);
  noFill();
  noLoop();
  scalar = width * 1.0 / col_num; // 描画ウィンドウと行の数からタイルの大きさを決定
  makeTriangleVector(); // 三角格子を張るベクトルの生成
  makeLattice(); // 格子点ベクトルを生成
  makeTileP6(); // タイルを生成
  drawTiling(); // タイリングを描画
}

// 三角格子を張るベクトルを生成する関数
void makeTriangleVector(){
  base[0] = new PVector(1.0, 0.0);
  base[1] = PVector.fromAngle(PI / 3);
}

// 三角格子を生成する関数
void makeLattice(){
  int row_num = ceil(col_num / base[1].x); // 行の数
  lattice = new PVector[col_num + 3][row_num + 1];
  for (int i = 0; i < col_num + 3; i++){
    for (int j = 0; j < row_num + 1; j++){
      PVector v = PVector.mult(base[0], (i-3) * scalar * sqrt(7.0)/2.0 ); 
      v.add(PVector.mult(base[1], j * scalar * sqrt(7.0)/2.0 ) );
      lattice[i][j] = v;
    }
  }
}

// 五角形を生成する関数(基本図形)
PShape makePentagon(){
  
  PVector[] v = new PVector[5]; // 五角形の頂点
  float theta = acos(5.0 / 2.0 / sqrt(7.0) );
  v[0] = new PVector(0.0,0.0);
  v[1] = PVector.fromAngle( -radians( 120.0 ) - theta ).mult( scalar );
  v[4] = PVector.fromAngle( radians( 180.0 ) - theta ).mult( scalar );
  v[3] = v[4].copy().add( v[1].copy() );
  v[2] = v[3].copy().add( v[1].copy().rotate( radians(90.0) ).mult( 1.0/sqrt(3.0) ) );

  PShape pentagon = createShape(GROUP);
  // 正六角形の一部となる正三角形を描く
  fill(0,0,255);
  noStroke();
  PShape tri = createShape();
  tri.beginShape(); 
  tri.vertex(v[0].x, v[0].y);
  tri.vertex(v[1].x, v[1].y);
  tri.vertex(v[4].x, v[4].y);
  tri.endShape(CLOSE);
  pentagon.addChild(tri);
  
  // 正三角形を描く
  fill(0,255,0);
  stroke(0,0,0);
  tri = createShape();
  tri.beginShape(); 
  tri.vertex(v[1].x, v[1].y);
  tri.vertex(v[3].x, v[3].y);
  tri.vertex(v[4].x, v[4].y);
  tri.endShape(CLOSE);
  pentagon.addChild(tri);

  // 正三角形の一部となる二等辺三角形を描く
  fill(0,0,255);
  noStroke();
  tri = createShape();
  tri.beginShape(); 
  tri.vertex(v[1].x, v[1].y);
  tri.vertex(v[2].x, v[2].y);
  tri.vertex(v[3].x, v[3].y);
  tri.endShape(CLOSE);
  pentagon.addChild(tri);
 
  return pentagon;
}

// タイルを生成する関数
void makeTileP6(){
  tile = createShape(GROUP); // PShapeのグループを作る

  for (int i=0; i<6; i++){
    PShape pentagon = makePentagon(); // 変形した五角形の生成
    pentagon.rotate(PI * i / 3); // 60度回転
    tile.addChild(pentagon); // グループに追加
  }
}

// 格子形状に合わせたタイリングを描画する関数
void drawTiling(){
//  background(255);
  for (int i=0; i<lattice.length; i++){
    for (int j=0; j<lattice[0].length; j++){
      if( i%2 == 0 && j%2 == 0 ){
        tile.resetMatrix();
        tile.translate(lattice[i][j].x, lattice[i][j].y); // タイルの位置を指定
        shape(tile); // タイルを描画
      }
    }
  }
}

参考

参考までに、アイソヘドラルタイリングIH11(P6)IH34(P6)IH90(P6)とみなしたときの基本図形を示しておきます。ただし、いずれのアイソヘドラルタイリングも基本図形をそのまま利用するのではなく、対称性を保ちつつ変形したものになります。

IH11(P6)とした場合の基本図形
IH34(P6)とした場合の基本図形
IH90(P6)とした場合の基本図形