Creative Coding Blog

Maths, coding and art

Basic tiling

One of the great things about computer art is that if you want to draw the same thing 1000 times, it is no more difficult than drawing it once. You just use a loop.

And in fact, it isn’t too difficult to draw 1000 variations of the same this, you just use a loop with some variables.

Here we will look at some very simple examples of tiling - repeating a similar pattern over an image.

Tiling dots

In this example, we will draw some dots on an image. We will draw 60 rows of 60 dots. For a bit of variety, we will randomise the colour.

Here is the code:

int TILE_SIZE = 10;

void tile()
{
    noStroke();
    fill(random(0, 100), 50, 50);
    ellipse(5, 5, 8, 8);
}

void setup()
{
    size(600, 600);
}

void draw()
{
    clear();
    colorMode(HSB, 100);
    background(100);

    for (int i = 0; i < 600; i+= TILE_SIZE)
    {
      for (int j = 0; j < 600; j+= TILE_SIZE)
      {
        pushMatrix();
        translate(i, j);
        tile();
        popMatrix();
      }
    }
}

In the draw function, we have a double loop that loops over every value of i from 0 to 600 is steps of 10, and then loops over every value of j from 0 to 600 in steps of 10. This double loop visits every 10 by 10 tile in the image.

For each tile we execute pushMatrix to store the current position. We then translate to (i,j), which positions the origin of the coordinate system at the top left of the current tile. We call tile to draw the tile, and popMatrix to restore the current position.

The tile function sets a random colour, then draws a circle using the ellipse function. The circle is centred at (5, 5), with a radius of 8. Since we have already translated the coordinate system to the point (i,j), this draws a circle at the centre of the current tile.

One thing worth noticing is that we have set the colorMode to HSB. When we call the fill function to set the fill colour, we use a random hue value, which sets a random colour. But the saturation and brightness are both set at 50, so the different colours are all slightly harmonised. Using completely random colours would not look so good.

Tiling with diagonal lines

As a second, classic, example we will use tiles that simply contain a diagonal line from one corner of the tile to the other. The diagonal line will either go from top to bottom ╲ or from bottom to top ╱ picked at random.

Here is the image:

The only code change is the tile function:

void tile()
{
    noFill();
    strokeWeight(2);
    stroke(50, 50, 50);
    if (random(0, 1) > 0.5)
      line(0, 0, TILE_SIZE, TILE_SIZE);
    else
      line(0, TILE_SIZE, TILE_SIZE, 0);
}

It is quite astonishing how two simple tiles and a simple rule can create such a pattern! This is because the tiles join up where they meet at each corner, to form L, T and box shapes which give the illusion of complexity.

In the next example we will use 4 tile types - both diagonals, a horizontal line and a vertical line. We will also run the ode twice, using different colours (and some transparency so that second colour doesn’t mask out the first where they overlap). Since the tile selection is random, then of course the second run of the code will produce a different pattern to the first.

Here is the result:

And here is the code:

void tile()
{
int TILE_SIZE = 10;

void tile()
{
    noFill();
    strokeWeight(2);
    float rand = random(0, 4);
    if (rand < 1)
      line(0, 0, TILE_SIZE, TILE_SIZE);
    else if (rand < 2)
      line(0, TILE_SIZE, TILE_SIZE, 0);
    else if (rand < 3)
      line(0, 0, 0, TILE_SIZE);
    else 
      line(0, TILE_SIZE, TILE_SIZE, TILE_SIZE);
}

void setup()
{
    size(600, 600);
}

void draw()
{
    clear();
    colorMode(HSB, 100);
    background(0);

    stroke(20, 50, 100, 50);
    for (int i = 0; i < 600; i+= TILE_SIZE)
    {
      for (int j = 0; j < 600; j+= TILE_SIZE)
      {
        pushMatrix();
        translate(i, j);
        tile();
        popMatrix();
      }
    }

    stroke(80, 50, 100, 50);
    for (int i = 0; i < 600; i+= TILE_SIZE)
    {
      for (int j = 0; j < 600; j+= TILE_SIZE)
      {
        pushMatrix();
        translate(i, j);
        tile();
        popMatrix();
      }
    }
}