How do I control turtle's self._newline()?

佐手、 提交于 2019-12-23 01:45:30

问题


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

回答1:


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

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

References

  • PyBook Chapter 13: Turtle Graphics (pdf)



回答2:


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


来源:https://stackoverflow.com/questions/9342861/how-do-i-control-turtles-self-newline

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!