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

Python Pygame实现龙曲线 列表浅拷贝引发旋转异常问题

问题原因

你遇到的双列表同步被修改的问题,根源是Python列表的浅拷贝机制。
copy_object()中调用的list.copy()仅做浅拷贝:只会复制最外层的列表对象,列表内部存储的线段坐标子列表(每个线段的起点、终点都是独立列表)仍然和原current_shape中的子列表共享内存引用。此时修改next_shape里任意线段的坐标值,本质是在修改两个列表共用的子对象,自然会出现current_shape被同步改动的现象。

除此之外你的代码还有两个逻辑错误,会导致迭代次数超过1次后龙曲线完全变形:

  • 现有rotate_next()方法没有做几何意义上的整体图形旋转,只是按固定三角函数偏移修改了线段终点坐标,完全没有以拼接点为旋转中心做坐标变换
  • counter计数逻辑放在draw()的线段遍历循环中,每绘制一条线段就减1,根本无法控制迭代次数
修复方法
  • 替换浅拷贝为深拷贝:导入标准库copy模块,使用copy.deepcopy()复制图形,保证复制出的next_shape所有层级的坐标对象都和原图形完全独立,不存在引用共享。
  • 补全正确的旋转逻辑:龙曲线每一轮迭代的拼接规则是以当前图形的最后一个端点为旋转中心,将复制出的整段图形顺时针旋转90度,再反向拼接在原图形末尾,需要对复制段的每一个线段端点都做旋转变换。
  • 调整计数逻辑:将迭代计数的递减逻辑放在图形生成步骤中,每完成一次完整的图形迭代再减1,计数归零时停止生成新图形。
修正后可运行代码
import pygame
from math import cos, sin, pi
import copy

class Curve:
    def __init__(self, shape_start, multiplier, counter):
        self.multiplier = multiplier
        # 初始化基础线段:水平向右
        self.current_shape = [
            [list(shape_start), [shape_start[0] + multiplier, shape_start[1]]]
        ]
        self.iter_remaining = counter
        self.next_shape = []

    @staticmethod
    def _rotate_point(point, center, degrees):
        """绕指定中心旋转点坐标,返回旋转后的整数坐标"""
        rad = degrees / 180 * pi
        rel_x, rel_y = point[0] - center[0], point[1] - center[1]
        rot_x = int(rel_x * cos(rad) - rel_y * sin(rad) + center[0])
        rot_y = int(rel_x * sin(rad) + rel_y * cos(rad) + center[1])
        return [rot_x, rot_y]

    def generate_next_iter(self):
        if self.iter_remaining <= 0:
            return
        # 深拷贝当前图形,避免引用共享
        origin_copy = copy.deepcopy(self.current_shape)
        # 旋转中心为当前图形的末端点
        rot_center = self.current_shape[-1][1]
        rotated_segment = []
        # 反向遍历复制段,每个点绕中心顺时针转90度
        for line in reversed(origin_copy):
            p1 = self._rotate_point(line[0], rot_center, -90)
            p2 = self._rotate_point(line[1], rot_center, -90)
            rotated_segment.append([p1, p2])
        # 合并图形
        self.current_shape += rotated_segment
        self.iter_remaining -= 1

    def draw(self, display):
        for line in self.current_shape:
            pygame.draw.line(display, (100, 100, 255), tuple(line[0]), tuple(line[1]), 2)
调用说明

你不需要再分步调用copy、rotate、merge方法,每次需要生成下一级龙曲线时,直接调用一次dragoncurve.generate_next_iter()即可,达到设定的迭代次数后方法会自动停止生成,不会无限递归。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 00:18:26