【问题标题】:How do I control turtle's self._newline()?如何控制海龟的 self._newline()?
【发布时间】:2012-02-18 16:24:52
【问题描述】:

我需要弄清楚如何在turtle.py 中控制self._newline()。我在我的 python Mandelbrot set 程序中发现了这一点,当时它开始做一些奇怪的事情;有关详细信息,请参阅Why is turtle lightening pixels?。然而,当我试图制作一个极其相似的程序来绘制复数的正切时,同样的事情并没有发生……但随着时间的推移,程序的速度大大降低了。

基本上,我要问 3 个问题:

导致这种差异的这些程序之间有什么区别? (智力探究)

如何激活/停止 self._newline()? (必要的,主要问题)

如何防止 self._newline() 导致颜色偏差(DSM 建议我将 self._pencolor() 引用插入到 turtle.py 中,但我不知道该怎么做)? (没有必要,但需要)

即使您没有回答中间问题,您的意见仍将不胜感激!

复杂的切线代码:

import turtle
import math
import cmath
turtle.speed(0)
def bengant(size, onelen):
    turtle.left(90)
    for x in range(-size*onelen, size*onelen+1):
        turtle.up()
        turtle.goto(x, -size*onelen-1)
        turtle.down()
        for y in range(-size*onelen, size*onelen+1):
            c = complex(x*1.0/onelen,y*1.0/onelen)
            k = cmath.tan(c)
            turtle.pencolor(0,math.atan(k.real)/math.pi+1/2,math.atan(k.imag)/math.pi+1/2)
            turtle.forward(1)
bengant(2,100)
x = raw_input("Press Enter to Exit")

【问题讨论】:

    标签: python api debugging turtle-graphics


    【解决方案1】:

    如何激活/停止 self._newline()? (必要的,主要问题)

    使用penup/pendown分别停止/激活self.__newline

    参考文献

    【讨论】:

    • 我在上面的benoit() 示例中尝试了这种方法,它可以有效地消除问题。但是,我发现如果您不小心,它还会创建额外的线路伪影和/或严重影响您的代码性能。我很想知道您使用这种技术对有问题的代码进行了修复。
    【解决方案2】:

    导致此问题的这些程序之间的区别是什么 差异?

    问题出现在您的bengant() 程序中出现频率不够高的长单色线条上。如果我让它更单色(即通过 0 作为第三颜色三元组而不是 math.atan(k.imag) / math.pi + 1/2),它就会出现:

    检测 Python 的海龟库可确认您在这些点上达到了优化子句。

    如何激活/停止 self._newline()?

    你没有。问题不在于这种优化存在,问题在于它的实现有问题。但正如您在最新的bengant() 程序中所见,当涉及到更多复杂性时,它就会消失。或许可以通过正确的示例向正确的人报告错误。

    如何防止 self._newline() 造成颜色偏差?

    就您的benoit() 代码而言,您可以使用 1.5 而不是默认的 1 的线宽来有效地消除它。它似乎不会对图像质量产生太大影响:

    左边是 1.0,右边是 1.5。但是,每 42 个像素的线条会消失。另一种方法是在您的颜色值中添加一些随机噪声(小部分添加),这些噪声不会影响人类的视觉效果,但不会触发麻烦的优化。

    这是我对您的 benoit() 代码的修改和一些速度优化:

    import turtle
    
    def benoit(onelen):
        turtle.tracer(False)
        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)
                g = 0
    
                for k in range(20):
                    z = z * z + c
                    if abs(z) > 2:
                        g = 0.2 + 0.8 * (20 - k) / 20
                        break
    
                turtle.pencolor(0, g, 0)
                turtle.forward(1)
    
            turtle.update()
    
        turtle.tracer(True)
    
    turtle.setup(1000, 750)
    turtle.hideturtle()
    turtle.setundobuffer(None)
    turtle.pensize(1.5)  # work around for "42" glitch
    
    benoit(250)
    
    turtle.exitonclick()
    

    这是我对您的bengant() 代码的类似修改:

    import math
    import cmath
    import turtle
    
    def bengant(size, onelen):
        turtle.tracer(False)
    
        turtle.left(90)
    
        size_onelen = size * onelen
    
        for x in range(-size_onelen, size_onelen + 1):
            turtle.up()
            turtle.goto(x, -size_onelen - 1)
            turtle.down()
    
            for y in range(-size_onelen, size_onelen + 1):
                c = complex(x * 1.0 / onelen, y  * 1.0 / onelen)
                k = cmath.tan(c)
                turtle.pencolor(0, math.atan(k.real) / math.pi + 1/2, math.atan(k.imag) / math.pi + 1/2)
                turtle.forward(1)
    
            turtle.update()
    
        turtle.tracer(True)
    
    turtle.hideturtle()
    
    bengant(2, 100)
    
    turtle.exitonclick()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-12
      • 1970-01-01
      • 1970-01-01
      • 2013-10-09
      • 2018-05-30
      相关资源
      最近更新 更多