Как создать тесселяцию Радужный треугольник - PullRequest
0 голосов
/ 04 мая 2019

Я пытаюсь создать тесселяцию треугольника, подобную следующей в Python:

image

Все, что я получил, это треугольник Серпенского.Я предполагаю, что он использовал бы один и тот же код.

import turtle as t
import math
import colorsys

t.hideturtle()
t.speed(0)
t.tracer(0,0)

h = 0
def draw_tri(x,y,size):
    global h
    t.up()
    t.goto(x,y)
    t.seth(0)
    t.down()
    color = colorsys.hsv_to_rgb(h,1,1)
    h += 0.1
    t.color(color)
    t.left(120)
    t.fd(size)
    t.left(120)
    t.fd(size)
    t.end_fill()

def draw_s(x,y,size,n):
    if n == 0:
        draw_tri(x,y,size)
        return

    draw_s(x,y,size/2,n-1)
    draw_s(x+size/2,y,size/2,n-1)
    draw_s(x+size/4,y+size*math.sqrt(3)/4,size/2,n-1)

draw_s(-300,-250,600,6)
t.update()

Ответы [ 2 ]

0 голосов
/ 04 мая 2019

Как отмечает @ReblochonMasque, существует несколько подходов к проблеме. Вот пример, который я разработал, чтобы использовать как можно меньше кода черепахи для решения проблемы:

from turtle import Screen, Turtle

TRIANGLE_SIDE = 60
TRIANGLE_HEIGHT = TRIANGLE_SIDE * 3 ** 0.5 / 2
CURSOR_SIZE = 20

screen = Screen()

width = TRIANGLE_SIDE * (screen.window_width() // TRIANGLE_SIDE)
height = TRIANGLE_HEIGHT * (screen.window_height() // TRIANGLE_HEIGHT)

diagonal = width + height

turtle = Turtle('square', visible=False)
turtle.shapesize(diagonal / CURSOR_SIZE, 1 / CURSOR_SIZE)
turtle.penup()
turtle.sety(height/2)
turtle.setheading(270)

turtle = turtle.clone()
turtle.setx(width/2)
turtle.setheading(210)

turtle = turtle.clone()
turtle.setx(-width/2)
turtle.setheading(330)

for _ in range(int(diagonal / TRIANGLE_HEIGHT)):
    for turtle in screen.turtles():
        turtle.forward(TRIANGLE_HEIGHT)
        turtle.stamp()

screen.exitonclick()

Вероятно, он может использовать оптимизацию, но он выполняет свою работу. И это интересно смотреть ...

0 голосов
/ 04 мая 2019

Существуют различные подходы;В следующем примере все сегменты линий создаются перед тем, как указывать turtle для их рисования на холсте.

import turtle as t
import math


WIDTH, HEIGHT = 800, 800
OFFSET = -WIDTH // 2, -HEIGHT // 2


class Point:
    """convenience for point arithmetic
    """
    def __init__(self, x=0, y=0):
        self.x, self.y = x, y
    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)
    def __iter__(self):
        yield self.x
        yield self.y


def get_line_segments(side_length=50):
    """calculates the coordinates of all vertices
       organizes them by line segment
       stores the segments in a container and returns it
    """
    triangle_height = int(side_length * math.sqrt(3) / 2)
    half_side = side_length // 2
    p0 = Point(0, 0)
    p1 = Point(0, side_length)
    p2 = Point(triangle_height, half_side)

    segments = []

    for idx, x in enumerate(range(-triangle_height, WIDTH+1, triangle_height)):
        for y in range(-side_length, HEIGHT+1, side_length):
            y += half_side * (idx%2 + 1)
            offset = Point(x, y)
            pa, pb, pc = p0 + offset, p1 + offset,p2 + offset
            segments += [[pa, pb], [pb, pc], [pc, pa]]

    return segments


def draw_segment(segment):
    p0, p1 = segment
    p0, p1 = p0 + offset, p1 + offset
    t.penup()
    t.goto(p0)
    t.pendown()
    t.goto(p1)


def draw_tiling():
    for segment in get_line_segments():
        draw_segment(segment)


t.hideturtle()
t.speed(0)
t.tracer(0,0)
offset = Point(*OFFSET)

draw_tiling()

t.update()
t.exitonclick()

Если вы хотите посмотреть, как отслеживается мозаика , вы можете заменитьследующие строки:

# t.hideturtle()
t.speed(1)
# t.tracer(0, 0)

и увеличьте экран холста с помощью мыши, чтобы увидеть границу плитки (я сделал так, чтобы она перекрывала стандартный размер окна)

...