You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Turtle谢尔宾斯基分形问题:正方形无法生成图案

谢尔宾斯基分形程序正方形异常问题解决

问题现象

正方形分形异常效果

用户提供的代码如下:

import turtle
import random
import math
import time

def is_point_inside_shape(x, y, vertices):
    # Use ray-casting algorithm to check if point is inside the shape
    num_intersections = 0
    for i in range(len(vertices)):
        p1 = vertices[i]
        p2 = vertices[(i+1) % len(vertices)]
        if p1[2] <= y < p2[2] or p2[2] <= y < p1[2]:
            if x < (p2[0] - p1[0]) * (y - p1[2]) / (p2[2] - p1[2]) + p1[0]:
                num_intersections += 1
    return num_intersections % 2 == 1

def add_points(num_sides, side_length, iterations, distance, speed):
    # Set up the turtle
    t = turtle.Turtle()
    t.speed(10)
    t.ht()
    t.penup()

    # Create vertices
    vertices = []
    angle = 2 * math.pi / num_sides
    for i in range(num_sides):
        x = side_length * math.cos(angle * i)
        y = side_length * math.sin(angle * i)
        vertices.append((x, y))

    # Draw the outline of the shape
    t.goto(vertices[0])
    t.pendown()
    for i in range(num_sides):
        t.goto(vertices[i])
    t.goto(vertices[0])

    # Draw a random point inside the shape
    t.penup()
    while True:
        x, y = random.uniform(-side_length/2, side_length/2), random.uniform(-side_length/2, side_length/2)
        if is_point_inside_shape(x, y, vertices):
            # Draw the point and break the loop
            t.goto(x, y)
            t.dot(4, 'red')
            break

    # Iterate and draw points
    t.speed(speed)
    for i in range(iterations):
        # Choose a random vertex
        vertex = random.choice(vertices)

        # Calculate the distance between the current position and the chosen vertex
        dx = (vertex[0] - t.xcor()) * distance
        dy = (vertex[2] - t.ycor()) * distance

        # Move the turtle to the new position
        t.goto(t.xcor() + dx, t.ycor() + dy)

        # Draw a dot at the new position
        t.dot(2, 'blue')

    # Done drawing
    t.penup()
    turtle.done()

#add_points(num_sides, side_length, num_points, distance from vertex, speed)
add_points(5, 250, 10000, 0.5, 3)

用户问题:我使用Python Turtle编写谢尔宾斯基分形生成程序,可生成指定边数的正多边形,通过迭代将点移动到当前点与随机顶点的指定距离处绘制分形。目前除正方形外,其他多边形均可正常生成图案,但正方形的点无法形成预期分形。

问题原因

代码存在两处索引错误:

  • is_point_inside_shape函数中,错误使用索引2访问顶点的y坐标,但顶点存储的是(x, y)二元组,y坐标的正确索引是1。
  • 迭代绘制部分计算dy时,同样错误使用vertex[2]获取顶点y坐标,应改为vertex[1]。

这些错误导致正方形的点内外判断逻辑失效、点移动计算错误,最终无法生成预期分形。

修正后的代码

import turtle
import random
import math
import time

def is_point_inside_shape(x, y, vertices):
    # 射线法判断点是否在图形内部
    num_intersections = 0
    for i in range(len(vertices)):
        p1 = vertices[i]
        p2 = vertices[(i+1) % len(vertices)]
        # 修正y坐标索引为1
        if p1[1] <= y < p2[1] or p2[1] <= y < p1[1]:
            if x < (p2[0] - p1[0]) * (y - p1[1]) / (p2[1] - p1[1]) + p1[0]:
                num_intersections += 1
    return num_intersections % 2 == 1

def add_points(num_sides, side_length, iterations, distance, speed):
    # 初始化turtle
    t = turtle.Turtle()
    t.speed(10)
    t.ht()
    t.penup()

    # 创建顶点
    vertices = []
    angle = 2 * math.pi / num_sides
    for i in range(num_sides):
        x = side_length * math.cos(angle * i)
        y = side_length * math.sin(angle * i)
        vertices.append((x, y))

    # 绘制图形轮廓
    t.goto(vertices[0])
    t.pendown()
    for i in range(num_sides):
        t.goto(vertices[i])
    t.goto(vertices[0])

    # 在图形内随机选一个初始点
    t.penup()
    while True:
        x, y = random.uniform(-side_length/2, side_length/2), random.uniform(-side_length/2, side_length/2)
        if is_point_inside_shape(x, y, vertices):
            t.goto(x, y)
            t.dot(4, 'red')
            break

    # 迭代绘制分形点
    t.speed(speed)
    for i in range(iterations):
        vertex = random.choice(vertices)
        # 修正dy计算中的顶点y坐标索引
        dx = (vertex[0] - t.xcor()) * distance
        dy = (vertex[1] - t.ycor()) * distance
        t.goto(t.xcor() + dx, t.ycor() + dy)
        t.dot(2, 'blue')

    t.penup()
    turtle.done()

# 调用示例:正方形分形
add_points(4, 250, 10000, 0.5, 3)

验证效果

修正后调用add_points(4, 250, 10000, 0.5, 3)即可生成正方形的谢尔宾斯基分形图案,其他多边形的生成逻辑不受影响,仍可正常运行。

内容的提问来源于stack exchange,提问作者Joe Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:37:14