Как тесселяции этой формы? - PullRequest
2 голосов
/ 17 апреля 2019

Я пытаюсь создать тесселяцию следующей формы, как показано на рисунке ниже.(У меня недостаточно репутации, чтобы публиковать изображения, так что вот оно. Я использую графику черепахи питона, чтобы попытаться подогнать каждую фигуру друг к другу, но я не знаю, как и когда заставить ее начинать заново.

Я уже сделал форму, как показано ниже.

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)

Я не знаю, куда идти отсюда, и код прямо сейчас создает базовую форму.

Ответы [ 2 ]

4 голосов
/ 18 апреля 2019

Вот еще один способ думать об этой проблеме. Многие тесселяции являются деформациями более простых геометрических плиток. Это можно считать деформированным шестиугольником:

enter image description here

Так что, если мы напишем код для разбиения плоскости на шестиугольник, то мы сможем использовать этот же код для разбиения его на фигуру. Программа для нанесения покрытий на шестигранные марки:

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

Одна проблема с заменой дизайна ОП заключается в том, что источник находится не в центре:

enter image description here

Но мы наденем это вместо того, чтобы исправить код рисования. Давайте изменим мой код выше, чтобы использовать код OP для рисования фигуры:

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()

Что дает нам модифицированный шестиугольник тесселяции:

enter image description here

0 голосов
/ 17 апреля 2019

Вы можете создать функцию, которая рисует полную фигуру

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

И тогда вы можете нарисовать одну figure и использовать penup(), forward(), pendown() и т. Д., Чтобы переместить черепаху, прежде чем вы начнете рисовать вторую figure.

Я экспериментировал с разными комбинациями и получаю что-то вроде этого

example1 ()

enter image description here

example2 ()

enter image description here

Вероятно, пример1 с некоторой рекурсией может дать ожидаемый результат.

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()

РЕДАКТИРОВАТЬ: с использованием рекурсии в figure Я сделал это

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()
...