2. Geometric patterns
VCMNA254: level 7: Design and implement mathematical algorithms using a simple general purpose programming language
constructing geometric patterns such as a honeycomb, using dynamic geometry functionality
2.1. Turtle basics
The python turtle module can be used to generate patterns of shapes.
2.2. Tessellation (tiling)
A tessellation is a repeated pattern in the plane or on a surface where shapes completely fill all the space around a given point where their boundaries meet.
For example, a honeycomb is a tessellation using hexagons.
Tiling patterns are tessellations using rectangular tiles or brick pavers in paths, mosaics in buildings, quilts and art.
A regular tessellation is created by tessellating regular polygons.
If more than one regular polygon is used, it is a semi-regular tessellation.
2.3. Square patterns
A grid of squares
Squares rotated 45 degrees.
Python code for both examples, where the initial angle can be set to 0 or 45 degrees.
1import turtle
2
3
4def square(t, length=50, start_pos=(0, 0), start_h=0, penw=1, penc="black", fillc=None):
5 """Draw a square given side length, turning clockwise.
6
7 Args:
8 t (class turtle.Turtle): turtle instance.
9 length (int, optional): side length. Defaults to 50.
10 start_pos (tuple, optional): start position. Defaults to (0, 0).
11 start_h (int, optional): initial heading. Defaults to 0.
12 penw (int, optional): pensize. Defaults to 1.
13 penc (str, optional): pencolor. Defaults to "black".
14 fillc (str, optional): fillcolor. Defaults to None.
15
16 """
17 t.pu()
18 t.goto(start_pos)
19 t.pd()
20 t.seth(start_h)
21
22 t.pensize(penw)
23 t.pencolor(penc)
24
25 if fillc is not None:
26 t.fillcolor(fillc)
27 t.begin_fill()
28
29 for _ in range(4):
30 t.fd(length)
31 t.rt(90)
32
33 if fillc is not None:
34 t.end_fill()
35
36
37def tes_square(t, screen_width, screen_height, side_length, start_h=0):
38 xrep = screen_width // side_length
39 yrep = screen_height // side_length
40 for i in range(yrep):
41 for j in range(xrep):
42 start_pos = (-screen_width//2 + (j * side_length), screen_height//2 - (i * side_length))
43 square(t, length=side_length, start_pos=start_pos, start_h=start_h)
44
45
46def main():
47 SCREEN_WIDTH = 810
48 SCREEN_HEIGHT = 610
49 SIDE_LENGTH = 50
50 START_H = 0
51
52
53 # Set up the turtle screen
54 s = turtle.Screen()
55 s.bgcolor("white")
56 s.title("draw_quares")
57 s.setup(width=SCREEN_WIDTH, height=SCREEN_HEIGHT, startx=0, starty=0)
58 s.tracer(0, 0)
59
60 # Create a turtle object
61 t = turtle.Turtle()
62 t.speed(0) # Set the turtle's speed to the fastest
63 t.ht()
64
65 tes_square(t, screen_width=SCREEN_WIDTH, screen_height=SCREEN_HEIGHT, side_length=SIDE_LENGTH, start_h=START_H)
66
67 s.update()
68 s.exitonclick()
69
70
71if __name__ == "__main__":
72 main()
2.4. Hexagon patterns
Aligned touching hexagons creating diamond gaps.
Python code:
1import turtle
2
3
4def hexagon(t, length=50, start_pos=(0, 0), start_h=60, penw=1, penc="black", fillc=None):
5 """Draw a square given side length, from centre left at 60 degrees, turning clockwise.
6
7 Args:
8 t (class turtle.Turtle): turtle instance.
9 length (int, optional): side length. Defaults to 50.
10 start_pos (tuple, optional): start position. Defaults to (0, 0).
11 start_h (int, optional): initial heading. Defaults to 0.
12 penw (int, optional): pensize. Defaults to 1.
13 penc (str, optional): pencolor. Defaults to "black".
14 fillc (str, optional): fillcolor. Defaults to None.
15
16 """
17 t.pu()
18 t.goto(start_pos)
19 t.pd()
20 t.seth(start_h)
21
22 t.pensize(penw)
23 t.pencolor(penc)
24
25 if fillc is not None:
26 t.fillcolor(fillc)
27 t.begin_fill()
28
29 for _ in range(6):
30 t.fd(length)
31 t.rt(60)
32
33 if fillc is not None:
34 t.end_fill()
35
36
37def tes_hexagon(t, screen_width, screen_height, side_length, start_h=0):
38 slsqr3 = side_length * (3 ** 0.5)
39 xrep = int(screen_width / side_length)
40 yrep = int(screen_height / slsqr3) + 1
41 print(yrep)
42 for i in range(yrep):
43 for j in range(xrep):
44 start_pos = (-screen_width//2 + (j * 2 * side_length), screen_height//2 - (i * slsqr3))
45 hexagon(t, length=side_length, start_pos=start_pos, start_h=start_h)
46
47
48def main():
49 SCREEN_WIDTH = 810
50 SCREEN_HEIGHT = 610
51 SIDE_LENGTH = 50
52 START_H = 60
53
54
55 # Set up the turtle screen
56 s = turtle.Screen()
57 s.bgcolor("white")
58 s.title("hexagons and diamonds")
59 s.setup(width=SCREEN_WIDTH, height=SCREEN_HEIGHT, startx=0, starty=0)
60 s.tracer(0, 0)
61
62 # Create a turtle object
63 t = turtle.Turtle()
64 t.speed(0) # Set the turtle's speed to the fastest
65 t.ht()
66
67 tes_hexagon(t, screen_width=SCREEN_WIDTH, screen_height=SCREEN_HEIGHT, side_length=SIDE_LENGTH, start_h=START_H)
68
69 s.update()
70 s.exitonclick()
71
72
73if __name__ == "__main__":
74 main()
Staggered hexagons creating a tessalation with no overlap.
Python code:
1import turtle
2
3
4def hexagon(t, length=50, start_pos=(0, 0), start_h=60, penw=1, penc="black", fillc=None):
5 """Draw a square given side length, from centre left at 60 degrees, turning clockwise.
6
7 Args:
8 t (class turtle.Turtle): turtle instance.
9 length (int, optional): side length. Defaults to 50.
10 start_pos (tuple, optional): start position. Defaults to (0, 0).
11 start_h (int, optional): initial heading. Defaults to 0.
12 penw (int, optional): pensize. Defaults to 1.
13 penc (str, optional): pencolor. Defaults to "black".
14 fillc (str, optional): fillcolor. Defaults to None.
15
16 """
17 t.pu()
18 t.goto(start_pos)
19 t.pd()
20 t.seth(start_h)
21
22 t.pensize(penw)
23 t.pencolor(penc)
24
25 if fillc is not None:
26 t.fillcolor(fillc)
27 t.begin_fill()
28
29 for _ in range(6):
30 t.fd(length)
31 t.rt(60)
32
33 if fillc is not None:
34 t.end_fill()
35
36
37def tes_hexagon(t, screen_width, screen_height, side_length, start_h=0):
38 slsqr3 = side_length * (3 ** 0.5) * 0.5
39 xrep = int(screen_width / side_length)
40 yrep = int(screen_height / slsqr3)
41 print(yrep)
42 for i in range(yrep):
43 for j in range(xrep):
44 if (i % 2) == 0:
45 start_pos = (-screen_width//2 + (j * 3 * side_length), screen_height//2 - slsqr3 - (i * slsqr3))
46 else:
47 start_pos = (-screen_width//2 + (j * 3 * side_length) + (1.5 * side_length), screen_height//2 - slsqr3 - (i * slsqr3))
48 hexagon(t, length=side_length, start_pos=start_pos, start_h=start_h)
49
50
51def main():
52 SCREEN_WIDTH = 810
53 SCREEN_HEIGHT = 610
54 SIDE_LENGTH = 50
55 START_H = 60
56
57
58 # Set up the turtle screen
59 s = turtle.Screen()
60 s.bgcolor("white")
61 s.title("hexagons")
62 s.setup(width=SCREEN_WIDTH, height=SCREEN_HEIGHT, startx=0, starty=0)
63 s.tracer(0, 0)
64
65 # Create a turtle object
66 t = turtle.Turtle()
67 t.speed(0) # Set the turtle's speed to the fastest
68 t.ht()
69
70 tes_hexagon(t, screen_width=SCREEN_WIDTH, screen_height=SCREEN_HEIGHT, side_length=SIDE_LENGTH, start_h=START_H)
71
72 s.update()
73 s.exitonclick()
74
75
76if __name__ == "__main__":
77 main()
Overlapping hexagons. The overlap_factor can be varied from 0.5 for tiangles to 1.0 for hexagons with triangular gaps.
hexagons_overlap_50
hexagons_overlap_67
hexagons_overlap_75
hexagons_overlap_100
Python code:
1import turtle
2
3
4def draw_hexagon(t, x, y, side_length, start_h=0):
5 t.penup()
6 t.goto(x,y)
7 t.seth(start_h)
8 t.pendown()
9 for i in range(6):
10 t.forward(side_length)
11 t.right(60)
12
13def hexagonal_overlap(t, swidth, sheight, side_length, overlap_factor=0.75):
14 vert_overlap_factor = overlap_factor
15 hor_overlap_factor = overlap_factor * 2
16 side_height = side_length * 3**0.5
17 rows = int(sheight / (side_height * vert_overlap_factor))+2
18 cols = int(swidth / (side_length * vert_overlap_factor))+1
19 for i in range(rows):
20 y = sheight//2 + (1-i) * side_height * vert_overlap_factor
21 for j in range(cols):
22 x = -swidth//2 + (j-1) * side_length * hor_overlap_factor
23 if i % 2 == 1:
24 x += side_length * vert_overlap_factor
25 draw_hexagon(t, x, y, side_length)
26
27
28
29s = turtle.Screen()
30s.bgcolor("white")
31s.title("draw_centered_regular_polygon")
32s.setup(width=800, height=600, startx=None, starty=None)
33s.tracer(0, 0)
34
35t = turtle.Turtle()
36t.speed(0)
37t.ht()
38
39hexagonal_overlap(t, 800, 600, 50, overlap_factor=0.67)
40
41s.update()
42s.exitonclick()