如何控制海龟的 self._newline()?

发布于 2025-01-07 10:25:21 字数 1081 浏览 0 评论 0原文

我需要弄清楚如何控制turtle.py中的self._newline()。我在我的 python Mandelbrot set 程序中发现了这一点,当时它开始做奇怪的事情;有关更多详细信息,请参阅为什么海龟会照亮像素?。然而,当我尝试制作一个极其相似的程序来绘制复数的正切图时,同样的事情没有发生……但随着时间的推移,程序的速度明显减慢。

基本上,我问 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")

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

生寂 2025-01-14 10:25:22

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

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

References

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

Use penup/pendown to respectively stop/activate self.__newline

References

追风人 2025-01-14 10:25:22

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

问题发生在长单色线上,而这种情况在您的 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()

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:

enter image description here

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:

enter image description here

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文