我如何控制海龟的 self._newline()? [英] How do I control turtle's self._newline()?

查看:15
本文介绍了我如何控制海龟的 self._newline()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要弄清楚如何控制turtle.py中的self._newline().我在我的 python Mandelbrot set 程序中发现了这一点,当时它开始做一些奇怪的事情;有关更多详细信息,请参阅

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

<块引用>

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

你没有.问题不在于这个优化存在,问题在于它的实现有问题.但是正如您在最新的 bengant() 程序中看到的那样,当涉及更多复杂性时,它就会消失.也许是用正确的例子向正确的人报告错误.

<块引用>

如何防止 self._newline() 导致颜色偏差?

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

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

这是我对您的 benoit() 代码进行的修复和一些速度优化的返工:

导入海龟def benoit(onelen):海龟示踪剂(假)龟.left(90)对于范围内的 x(-2 * onelen,onelen):乌龟.up()龟.goto(x, int(-1.5 * onelen) - 1)乌龟.down()对于范围内的 y(int(-1.5 * onelen) - 1, int(1.5 * onelen) - 1):z = 复数 (0, 0)c = 复杂(x * 1.0/onelen,y * 1.0/onelen)克 = 0对于范围内的 k(20):z = z * z + c如果 abs(z) >2:g = 0.2 + 0.8 * (20 - k)/20休息乌龟.pencolor(0, g, 0)龟.forward(1)乌龟.更新()海龟示踪剂(真)龟.setup(1000, 750)海龟.hideturtle()海龟.setundobuffer(无)turtle.pensize(1.5) # 解决42"故障福利(250)海龟.exitonclick()

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

导入数学导入 cmath进口龟def bengant(大小,onelen):海龟示踪剂(假)龟.left(90)size_onelen = 大小 * onelen对于范围内的 x(-size_onelen,size_onelen + 1):乌龟.up()龟.goto(x, -size_onelen - 1)乌龟.down()对于范围内的 y(-size_onelen,size_onelen + 1):c = 复杂(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)龟.forward(1)乌龟.更新()海龟示踪剂(真)海龟.hideturtle()bengant(2, 100)海龟.exitonclick()

I need to figure out how to control the self._newline(), in turtle.py. I found out about this during my python Mandelbrot set program, when it started doing weird things; see Why is turtle lightening pixels? for more details. However, when I tried to make an extremely similar program that graphed the tangent of complex numbers, the same thing did not happen...but the program slowed down considerably over time.

Basically, I am asking 3 questions:

What is the difference between these programs that causes this discrepancy? (intellectual inquiry)

How do I activate/stop self._newline()? (Necessary, main question)

How do I keep self._newline() from causing color deviations (DSM suggested that I insert self._pencolor() references into turtle.py, but I have no idea how to do this)? (Not necessary, but desired)

Even if you do not answer the middle question, your input will still be greatly appreciated!

Complex tangent code:

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")

解决方案

What is the difference between these programs that causes this discrepancy?

The problem happens with long monochromatic lines which don't occur often enough in your bengant() program. If I make it more monochromatic (i.e. pass 0 as third color triple instead of math.atan(k.imag) / math.pi + 1/2) it makes an appearance:

Instrumenting Python's turtle library confirms you're hitting the optimization clause at these points.

How do I activate/stop self._newline()?

You don't. The problem isn't that this optimization exists, the problem is there's something wrong in its implementation. But as you can see in your latest bengant() program, it disappears when more complexity is involved. Perhaps a bug report to the right people with the right example.

How do I keep self._newline() from causing color deviations?

As far as your benoit() code goes, you can effectively eliminate it using a line width of 1.5 instead of the default 1. It doesn't seem to affect the image quality too much:

That's 1.0 on the left, 1.5 on the right. However, your lines every 42 pixels will disappear. Another approach would be to add some random noise (small fractional additions) to your color values that don't affect it visually for humans but keep the troublesome optimization from triggering.

Here's my rework of your benoit() code with this fix and some speed optimizations:

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()

Here's my rework of your bengant() code along similar lines:

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()

这篇关于我如何控制海龟的 self._newline()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆