如何创建彩虹三角形细分

2024-06-13 11:24:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在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()

Tags: 代码importsizedefmathlefttricolor
2条回答

正如@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()

它可能需要优化,但它完成了任务。看电影很有趣。。。你知道吗

有多种方法;下面的示例在引导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)

并用鼠标放大画布屏幕以查看平铺的边界(我使其与窗口的标准大小重叠)

相关问题 更多 >