为什么乌龟在变亮像素?

7 投票
2 回答
1967 浏览
提问于 2025-04-17 12:51

我写的一个程序用来生成曼德尔布罗特集合,但出现了个问题:每当笔的颜色改变时,之后每第42个像素的颜色都会变得更亮。这听起来有点巧合,叫做“曼德尔虫”(我刚学到这个词),因为在很多靠近“边缘”的像素上,它的表现不一致(可能会在应该是的颜色和上一个或下一个像素的颜色之间模糊),但每次颜色改变后,都是第42个像素出现这个问题。我使用的是OSX 10.6.8和PYTHON 2.7。当我在学校写这个程序时,一切都很好(在Windows上),然后我把它发给自己,稍微修改了一下(主要是增大了样本大小和图像),运行后就出现了这个问题。补充一下,我忘了提,这个问题只出现在我的曼德尔布罗特程序上,家里其他几个海龟程序都没问题。

这是一些截图(这样你就不用等程序运行完才能看到我说的内容):

这是我在家里第一版的截图:

我说,这到底是什么?

这是当前版本的截图(侧着的):

请注意:这张图片是侧着的

这是代码:

import turtle
import math
turtle.speed(0)
def benoit(onelen):
    turtle.left(90)
    for x in range(-2*onelen, onelen):
        turtle.up()
        turtle.goto(x, int(-1.5*onelen)-1)
        turtle.down()
        for y in range(int(-1.5*onelen)-1, int(1.5*onelen)-1):
            z = complex(0,0)
            c = complex(x*1.0/onelen,y*1.0/onelen)
            for k in range(20):
                z = z*z+c
                if abs(z) > 2:
                    g = .2 + .8*(20-k)/20
                    break
                if k == 19:
                    g = 0
            turtle.pencolor(0,g,0)
            turtle.forward(1)
benoit(250)
x = raw_input("Press Enter to Exityadayadayada")

补充:DSM提出了一个修复方法,他对这个bug很感兴趣。不过,我对编辑Python源代码没有经验,看到那些下划线让我有点紧张。有人能具体告诉我该编辑什么和/或怎么做吗?

2 个回答

1

我可以给你提个建议吗?

我试过你的代码,运行起来花了很长时间,你可能已经知道这一点,但你可能不知道的是有一个叫做 tracer 的函数……我只是在你代码的开头加了这个:

 wn=turtle.Screen()
 wn.tracer(10000)

这样就不需要使用 speed(0) 这个函数了 :)

试试这个,再运行一次,我试过了,整个图像在 62 秒内就渲染完成了,我是通过在开头导入时间模块来计时的,代码是:

 import time
 st=time.time()

然后在最后加上这段代码:

 print time.time()-st

顺便说一下,干得不错!我自己也做了一个,不过比你的慢得多,质量也低,主要是用一个方形的数组,然后在我想要的位置上盖章,哈哈,不过我会在未来努力改进,因为我上周才知道有 turtle 这个东西。

最后一件事,如果你输入:

 from turtle import *

而不是 "import turtle",那么你就不需要在每个函数调用前都加上 turtle 了 :) 其他模块也是一样的。

我还附上了你那个分形图的图片,它在我这台不算强大的机器上渲染了 62 秒你在我这台弱机器上运行的代码

希望这些对你有很大帮助。另外你会注意到我没有那个浅线条的问题,不知道你在上面的原始代码中是否解决了这个问题?

7

哇,这真是我见过的最有趣的一个bug之一。信不信由你,数字42的出现其实是有关系的!虽然只是间接的关系……

在turtle.py文件里:

   def _goto(self, end):
        """Move the pen to the point end, thereby drawing a line
        if pen is down. All other methodes for turtle movement depend
        on this one.

[...]

    ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
    self._position = end
    if self._creatingPoly:
        self._poly.append(end)
    if len(self.currentLine) > 42: # 42! answer to the ultimate question
                                   # of life, the universe and everything
        self._newLine()
    self._update() #count=True)

问题出现在它决定换行的时候,听说这是为了提高性能:

def _newLine(self, usePos=True):
    """Closes current line item and starts a new one.                                              
       Remark: if current line became too long, animation                                          
       performance (via _drawline) slowed down considerably.                                       
    """

我通过提高行号限制,或者在一些没有自我._pencolor引用的地方添加这些引用,来“修复”这个bug。不过你也不是疯了,这其实和你做的事情没什么关系。:-)

撰写回答