2

I am trying to tessellate the following shape, as shown in the image below. (I do not have enough reputation to post images, so here it is. I am using python turtle graphics to try and have each shape fit into each other, but I don't know how or when to make it start over again.

I have already made the shape, as seen below.

import turtle

t = turtle.Turtle()
t.left(30)
t.speed("fastest")
turtle.delay(0)
counter = 0 
t.begin_fill()
def setup(length):
    t.forward(length)
    t.right(120)
    t.forward(length / 3)
    t.left(60)
    t.forward(length / 3)
    t.left(120)
    t.forward(length)
    t.left(60)
    t.forward(length)
    t.left(120)
    t.forward(length / 3)
    t.left(60)
    t.forward(length / 3)
    t.right(120)
    t.forward(length)
    t.right(60)

while True:
    setup(100)

I don't know where to go from here, and the code right now just makes the base shape.

  • you run `setup()` again and again but you should draw one figure and change position before next figure. Put one `setup(), next `left()` or `right()` with some value and next second setup() (all without `while True`) to see how it changes your image. After that you can try to better value in left()/right() or you will have to use `penup/forward/pendown` to move it. Try it with different values and till you get two figures in correct places. – furas Apr 17 '19 at 07:40

2 Answers2

5

Here's another way to think about this problem. Many tessellations are deformations of simpler geometric tiles. This one can be thought of as a deformed hexagon:

enter image description here

So if we write code to tile the plane with a hexagon, then we should be able to use that same code to tile it with this shape. A stamp-based hexagon tiling program:

from turtle import Screen, Turtle
from math import pi, sin, cos

SIDES = 6
OUTER_RADIUS = 90
INNER_RADIUS = 3**0.5 * OUTER_RADIUS / 2

def tessellation(depth):
    turtle.stamp()

    if depth:
        angle = 0

        while angle < 2 * pi:

            position = turtle.position()

            x = 2 * INNER_RADIUS * cos(angle)
            y = 2 * INNER_RADIUS * sin(angle)

            turtle.goto(turtle.xcor() + x, turtle.ycor() + y)
            tessellation(depth - 1)

            turtle.setposition(position)

            angle += 2 * pi / SIDES

screen = Screen()

turtle = Turtle(visible=False)
turtle.penup()
turtle.sety(-OUTER_RADIUS)  # center point correction!
turtle.begin_poly()
turtle.circle(OUTER_RADIUS, steps=6)
turtle.end_poly()

screen.register_shape('tile', turtle.get_poly())

turtle.shape('tile')
turtle.settiltangle(30)  # orient tile
turtle.fillcolor('white')
turtle.home()
turtle.showturtle()

screen.tracer(False)  # because I have no patience
tessellation(2)
screen.tracer(True)

screen.exitonclick()

enter image description here

One issue with substituting the OP's design, is that the origin isn't in the center:

enter image description here

But we'll put a bandaid on this, rather than fix the drawing code. Let's modify my code above to use the OP's code to draw the figure:

from turtle import Screen, Turtle
from math import pi, sin, cos

SIDES = 6
OUTER_RADIUS = 90
INNER_RADIUS = 3**0.5 * OUTER_RADIUS / 2

def setup(length):
    turtle.forward(length)
    turtle.right(120)
    turtle.forward(length / 3)
    turtle.left(60)
    turtle.forward(length / 3)
    turtle.left(120)
    turtle.forward(length)
    turtle.left(60)
    turtle.forward(length)
    turtle.left(120)
    turtle.forward(length / 3)
    turtle.left(60)
    turtle.forward(length / 3)
    turtle.right(120)
    turtle.forward(length)
    turtle.right(60)

def figure(length):
    for _ in range(3):
        setup(length)

def tessellation(depth):
    turtle.stamp()

    if depth:
        angle = 0

        while angle < 2 * pi:

            position = turtle.position()

            x = 2 * INNER_RADIUS * cos(angle)
            y = 2 * INNER_RADIUS * sin(angle)

            turtle.goto(turtle.xcor() + x, turtle.ycor() + y)
            tessellation(depth - 1)

            turtle.setposition(position)

            angle += 2 * pi / SIDES

screen = Screen()

turtle = Turtle(visible=False)
turtle.penup()
turtle.goto(OUTER_RADIUS / 9, -2 * OUTER_RADIUS / 9)  # center point correction!
turtle.begin_poly()
figure(INNER_RADIUS)
turtle.end_poly()

screen.register_shape('tile', turtle.get_poly())

turtle.shape('tile')
turtle.settiltangle(30)  # orient tile
turtle.fillcolor('white')
turtle.home()
turtle.showturtle()

screen.tracer(False)  # because I have no patience
tessellation(2)
screen.tracer(True)

screen.exitonclick()

Which gives us the modifed hexagon tessellation:

enter image description here

cdlane
  • 40,441
  • 5
  • 32
  • 81
0

You could create function which draw full figure

def figure(length):
    setup(length)
    setup(length)
    setup(length)

And then you could draw one figure and use penup(), forward(), pendown(), etc. to move turtle before you draw second figure.

I experimented with different combinations and I get something like this

example1()

enter image description here

example2()

enter image description here

Probably example1 with some recursion could give expected result.

import turtle

# --- functions ---

def setup(length):
    t.forward(length)
    t.right(120)
    t.forward(length / 3)
    t.left(60)
    t.forward(length / 3)
    t.left(120)
    t.forward(length)
    t.left(60)
    t.forward(length)
    t.left(120)
    t.forward(length / 3)
    t.left(60)
    t.forward(length / 3)
    t.right(120)
    t.forward(length)
    t.right(60)

def figure(length):
    for _ in range(3):
        setup(length)

def example1(length):

    for _ in range(3):
        figure(length)

        t.penup()
        t.forward(length + length/3)
        t.right(120)
        t.backward(length/3)
        t.pendown()

def example2(length):

    for _ in range(3):
        figure(length)

        t.penup()
        t.left(60)
        t.forward(length + length)
        t.right(60)
        t.pendown()


# --- main ---

t = turtle.Turtle()
t.speed(0)
turtle.delay(0)

t.left(30)

#example1(50)
example2(50)

turtle.mainloop()

EDIT: using recursion in figure I made this

enter image description here

import turtle

# --- functions ---

def setup(length):
    t.forward(length)
    t.right(120)
    t.forward(length / 3)
    t.left(60)
    t.forward(length / 3)
    t.left(120)
    t.forward(length)
    t.left(60)
    t.forward(length)
    t.left(120)
    t.forward(length / 3)
    t.left(60)
    t.forward(length / 3)
    t.right(120)
    t.forward(length)
    t.right(60)

def figure(length, level=0):

    for _ in range(3):
        if level > 0:
            move(length)
            figure(length, level-1)

        setup(length)

def move(length):
    t.penup()
    t.left(60)
    t.forward(length + length)
    t.right(60)
    t.pendown()

# --- main ---

t = turtle.Turtle()
t.speed(0)
turtle.delay(0)

t.left(30)

figure(50, 2)

turtle.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148