如何创建彩虹三角形镶嵌

时间:2019-05-04 00:35:52

标签: python geometry turtle-graphics tiling

我正在尝试在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 :(得分:0)

有各种各样的方法;下面的示例在指示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)

并用鼠标放大画布屏幕以查看拼贴的边界(我将其与窗口的标准尺寸重叠)

答案 1 :(得分:0)

正如@ReblochonMasque所指出的,有多种解决方法。这是我制定的尽可能少使用乌龟代码来解决问题的方法:

-

它可能可以使用优化,但是可以完成工作。看着很有趣...