1. ホーム
  2. 壁紙アート
  3. 五角形によるタイリング
  4. 五角形によるタイリング(Type 1)

ここでは、15タイプある五角形によるタイリングのうち、Type 1のタイリングを再現してみました。なお、今回のタイリングを作成するにあたって、杉本晃久さんのサイトで紹介されている「凸五角形タイル張り問題」を参考にしました。

五角形によるタイリング(Type 1)

今回、再現した五角形によるタイリング(Type 1)は以下のような図形になります。

五角形によるタイリング(Type 1)

以下で、この五角形によるタイリング(Type 1)の描き方について解説していきます。

五角形によるタイリング(Type 1)の描き方

対称性について

まず、この五角形によるタイリング(Type 1)の対称性について考えます。

五角形によるタイリング(Type 1)の対称性

上図のように、タイリングのパターンをじっくり見ていくと、上図の赤丸の周りの180°回転に対して図形は回転対称になっていることが分かります。また、黒色の点を格子としてみると、並進対称性も持っていることが分かり、近接する4つの黒色の点同士が平行四辺形を形作っていることから、黒色の点は一般格子になっていることが分かります。これらをまとめると、五角形によるタイリング(Type 1)は、壁紙群P2の対称性を持つことが分かります。さらに言えば、アイソヘドラルタイリングIH23(P2)に分類されます。

五角形の準備

今回利用する五角形は以下のような図形になります。

Type 1の五角形

五角形の角度のうち、上図のA, B, Cの和が360°になるようにとります。特徴として、D+E=180°になることから、辺AEと辺CDは互いに平行となります。また、五角形を準備する際に、辺DEの中点を一般格子点(黒色の点)、辺ABの中点と辺BCの中点を180°回転の中心(赤色の点)としておくと、タイリングしやすくなります。

基本図形の準備

五角形によるタイリング(Type 1)の基本図形は、Type 1の五角形そのものになります。なお、今回は角Aを130°、角Dを75°にとり、また辺CDと辺ABをそれぞれ辺AEの長さの1.2倍と0.4倍になるようにとりました。

一般格子の準備

上記で説明したように、上図の黒丸や赤丸がそれぞれ一般格子点や隣り合う一般格子点同士の中点と一致するようにとりますので、それに伴い、一般格子の形状も決まってきます。つまり、一般格子を張る2つのベクトルは、辺DEの中点から辺BCの中点へのベクトルを2倍したものと、辺BCの中点から辺ABの中点へのベクトルを2倍したものとになります。

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

ここまで準備ができたら、あとは壁紙群P2の対称性に合わせて基本図形を並べていくことで五角形によるタイリング(Type 1)を行うことができます。

ソースコード

今回再現した五角形によるタイリング(Type 1)のプログラムのソースコードを示しておきます。

PVector[][] lattice; // 格子点ベクトル
PShape tile; // タイル
float pentagon_size = 100.0; // 五角形の基準サイズ
PVector[] v = new PVector[5]; // 基本図形を構成する五角形の座標
PVector[] base = new PVector[2]; // 格子を張るベクトル

void setup(){
  
  size(1000, 1000, P2D);
  noFill();

  makeTileP2(); // タイルを生成
  makeGeneralVector(); // 一般格子を張るベクトルの生成
  makeLattice(); // 格子点ベクトルを生成
  drawTiling(); // タイリングを描画
}

// 五角形の頂点を取得する関数
PVector[] getPentagon(){
  
  PVector[] v = new PVector[5];
  v[4] = PVector.fromAngle(radians(75.0)).mult(pentagon_size/2.0);
  v[3] = PVector.fromAngle(radians(-105.0)).mult(pentagon_size/2.0);
  v[0] = v[4].copy().add( new PVector(pentagon_size, 0.0) );
  v[2] = v[3].copy().add( new PVector(1.2 * pentagon_size, 0.0) );
  v[1] = v[0].copy().add( PVector.fromAngle(radians(-50.0)).mult(pentagon_size * 2.0/5.0));
  
  return v;
}

// 基本図形を生成する関数
PShape makeFundamentalShape(){
  // 五角形の座標を取得
  v = getPentagon();

  // 五角形を描く
  PShape pentagon = createShape();
  pentagon.beginShape(); 
  for(int j=0; j<5; j++){
    pentagon.vertex(v[j].x, v[j].y);
  }
  pentagon.endShape(CLOSE);
  
  return pentagon;
}

// タイルを生成する関数
void makeTileP2(){
  tile = createShape(GROUP); // PShapeのグループを作る
  for(int i=0; i<2; i++){    
    PShape pentagon = makeFundamentalShape(); // 6つの五角形で構成される図形の生成
    pentagon.rotate(PI * i); // 180度回転
    tile.addChild(pentagon); // グループに追加
  }
}

// 一般格子を張るベクトルを生成する関数
// 基本図形のサイズから算出する
void makeGeneralVector(){
  base[0] = v[1].copy().add( v[2].copy().sub(v[1].copy()).mult(0.5) ).mult(2.0);
  base[1] = v[0].copy().add( v[1].copy().sub(v[0].copy()).mult(0.5) );
  base[1] = base[1].sub( v[1].copy().add( v[2].copy().sub(v[1].copy()).mult(0.5) ) );
  base[1] = base[1].mult(2.0);
}

// 一般格子を生成する関数
void makeLattice(){
  int col_num = ceil(width / base[0].x) + 1; // 列数
  int row_num = ceil(height / base[1].y) + 1; // 行の数
  lattice = new PVector[col_num][row_num];
  for (int i = 0; i < col_num; i++){
    for (int j = 0; j < row_num; j++){
      PVector v = PVector.mult(base[0], i); 
      v.add(PVector.mult(base[1], j));
      lattice[i][j] = v.copy();
    }
  }
}

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

考察

五角形によるタイリング(Type 1)は、アイソヘドラルタイリングIH23(P2)に分類されることが分かりました。今回描いたType 1の五角形と記事IH23(P2)で紹介した基本図形とを比較してみると、前者の五角形は後者の五角形の拡張になっていることが分かります。つまり、記事IH23(P2)で紹介した基本図形は、今回描いたType 1の五角形において辺DEが2つの近接する一般格子点を結んだ直線と平行になるような特別なケースであるといえそうです。