Patterns

The jigsaw program can generate aperiodic tiling patterns. These are created by repeated divisions of an initial shape. The player can choose the Pattern, the number of divisions, the drawing style and the colours used. So far five basic pattern types are available: Pinwheel Triangles, Danzer Triangles, Robinson Triangles, Penrose Rhombs and The Chair.

Contents

All the patterns are generated by repeated division of an initial shape, and of the ones included the Pinwheel is the simplest to code. This page contains the basic code used to create the Pinwheel pattern and video examples of the generation processes.


class Triangle(object):
    """
    A triangle is 3 vertices stored as complex numbers and a type.
    For most applications the vertex order is important.
    """

    def __init__(self, vertex_a, vertex_b, vertex_c, triangle_type):
        self.vertex_a = vertex_a
        self.vertex_b = vertex_b
        self.vertex_c = vertex_c
        self.type = triangle_type
        self.middle = None

class Pinwheel(object):
    """
    Given a guide size (unit) and a division (division)
    return a pinwheel tiling.
    """
    def __init__(self, unit, max_division, cumulative):
        self.unit = int(unit / 2.)
        max_division = int(min(max_division, 4))
        vertex_a = complex(0.0, 0.0)
        vertex_b = complex(self.unit * 2.2, 0.0)
        vertex_c = complex(self.unit * 2.2, self.unit)
        vertex_d = complex(0.0, self.unit)

        triangles = [Triangle(vertex_a, vertex_b,
                              vertex_c, 0),
                     Triangle(vertex_c, vertex_d,
                              vertex_a, 0)]
        if cumulative:
            self.triangles = []
            for division in range(max_division):
                triangles = self.divide_triangles(triangles)
                self.triangles += triangles
        else:
            for division in range(max_division):
                triangles = self.divide_triangles(triangles)
            self.triangles = triangles



    def divide_triangles(self, triangles):
        res = []
        for triangle in triangles:
            res.extend(self.divide(triangle))
        return res


    def divide(self, triangle):
        factor = 0.4
        vertex_a = triangle.vertex_a
        vertex_b = triangle.vertex_b
        vertex_c = triangle.vertex_c
        vertex_f = vertex_a + (vertex_b - vertex_a) * 0.5
        vertex_e = vertex_a + (vertex_c - vertex_a) * factor
        vertex_d = vertex_a + (vertex_c - vertex_a) * factor * 2.0
        vertex_g = vertex_d + (vertex_b - vertex_d) * 0.5

        return [Triangle(vertex_a, vertex_e, vertex_f, 1),
                Triangle(vertex_d, vertex_e, vertex_f, 2),
                Triangle(vertex_f, vertex_g, vertex_d, 3),
                Triangle(vertex_f, vertex_g, vertex_b, 4),
                Triangle(vertex_b, vertex_d, vertex_c, 5)]

Pinwheel Example 1

A video from jigsaw showing the generation of a Pinwheel pattern using the "Random" style.

Pinwheel Example 2

A video from jigsaw showing the generation of a Pinwheel pattern using the "Type" style.

Danzer Example 1

A video from jigsaw showing the generation of a Danzer pattern using the "Type" style.

Danzer Example 2

A video from jigsaw showing the generation of a Danzer pattern using the "Outline" style.

Robinson Example 1

A video from jigsaw showing the generation of a Robinson pattern using the "Outline" style.

Robinson Example 2

A video from jigsaw showing the generation of a Robinson pattern using the "Type" style.

Rhombs Example 1

A video from jigsaw showing the generation of a Rhombs pattern using the "Random" style.

Chair Example 1

A video from jigsaw showing the generation of a Chair pattern using the "Orientation" style.

Chair Example 2

A video from jigsaw showing the generation of a Chair pattern using the "Type" style.