2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

壁紙群を使ってフェアアイル風模様を自動生成する

Last updated at Posted at 2025-12-10

はじめに

シェットランドというイギリス最北端に位置する群島地域で17世紀初頭に普及した編み込み模様をフェアアイルと呼びます。フェアアイル模様はOXO模様のような、小さなモチーフを規則正しく繰り返すことが特徴です。
私は自分でデザインしたものを編んで形にするのが好きなので普段からデザインを考えているのですが、デザインをするだけでかなりの時間がかかります。そこでフェアアイル模様の特徴である規則性や対称性をルール化し、自動生成できるようにすれば、デザイン時間を大幅に短縮できるのではないかと考えました。
模様の対称性を数学的に表現する手法として、壁紙群(Wallpaper Groups)とう概念があり、平面の繰り返し模様を 17 種類の対称性に分類するもので、フェアアイル模様の構造と相性が良いと考えました。
そこで今回は、壁紙群のひとつである「p4m」を使い、フェアアイル風の対称模様を Pythonで自動生成する仕組みを実装してみました。

壁紙群

壁紙群とは、平面に広がる繰り返し模様を「どんな対称性を持っているか」で分類した 17 種類のグループのことです。回転、鏡映、平行移動といった操作によって、模様がどのように自分自身と一致するかを表すため、タイル模様やイスラム幾何学、建築の装飾などあらゆるデザインの基礎となっています。
フェアアイル模様は基本的に四角いグリッドで構成されます。今回採用するp4mは90° 回転対称と鏡映対称という対称性をもつ壁紙群です。この対称性はフェアアイル模様で頻繁に用いられる模様の性質と非常に相性が良いです。

p4m対称性をプログラムで表現

0/1の二値でタイルを表現し、生成の仕組みとしては以下のように設計しました。
1.グリッド中心を決める
2.適当にセルを選び、p4mの対象操作(回転、鏡映)を行う
3.対象操作により影響の受けたセル同士をグループ化して、0,1を割り当てる
以上の仕組みにより対称的なモチーフがデザインできると考えた。

Pythonにて実装

基本タイル N×N の点 (i, j) が、p4m 対称群の作用で移る全ての点集合を返す関数。

import numpy as np
import random

def p4m_group(i, j, N):
    cx = cy = N // 2
    x = i - cx
    y = j - cy

    points = set()

    def add_point(x, y):
        ii = x + cx
        jj = y + cy
        if 0 <= ii < N and 0 <= jj < N:
            points.add((ii, jj))

    # 90° 回転を4回
    rotations = [
        ( x,  y),
        (-y,  x),
        (-x, -y),
        ( y, -x),
    ]

    for rx, ry in rotations:
        # 8種の変換
        add_point( rx,  ry)
        add_point(-rx,  ry)
        add_point( rx, -ry)
        add_point(-rx, -ry)

        # 対角線反射
        add_point( ry,  rx)
        add_point(-ry,  rx)
        add_point( ry, -rx)
        add_point(-ry, -rx)

    return points

次に0/1の二値でp4m対称を持つN×Nタイルを生成する関数を定義。

def generate_p4m_tile(N=15):
    assert N % 2 == 1

    pattern = np.zeros((N, N), dtype=int)
    assigned = set()

    for i in range(N):
        for j in range(N):
            if (i, j) in assigned:
                continue

            group = p4m_group(i, j, N)

            # 0or1をランダムに与える
            color = random.randint(0, 1)
            for (ii, jj) in group:
                pattern[ii, jj] = color
                assigned.add((ii, jj))

    return pattern

生成したモチーフを縦横方向に繰り返す関数を定義。

def tile_periodic(tile, repeat_x=4, repeat_y=4):
    return np.tile(tile, (repeat_y, repeat_x))

では、プロットしてみます!

import matplotlib.pyplot as plt

tile = generate_p4m_tile(N=15)
pattern = tile_periodic(tile, repeat_x=2, repeat_y=4)

# Plot
plt.figure(figsize=(6,6))
plt.imshow(pattern, cmap="binary", interpolation="nearest")
plt.axis("off")
plt.title("")
plt.show()

生成できたデザイン

無限にデザインを生成することに成功しました。しかも結構いいデザイン。アルゴリズムはいたって簡単ですが、とんでもないものができてしまった予感。

デザイン1
output1.png

デザイン2
output2.png

デザイン3
output3.png

デザイン4
output4.png

デザイン5
output6.png

まとめ

今回はフェアアイル風模様の自動生成に取り組みました。今まで方眼紙に手でデザインしていたのが、なんと一瞬で無限に生成できるようになりました。編み物好きの人はぜひ使ってみてください。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?