提高混沌游戏效率
Improving Chaos Game efficiency
我编写此脚本是为了使用 turtle 模块来复制我在 Numberphile 的频道上看到的混沌游戏。绘制了大量的点以使其在更大范围内运行良好。我假设大量的点是导致程序开始 运行 变慢的原因,我想知道是否有人可以帮我想出一个解决方法。
我愿意接受任何类型的解决方案,只要控件保持不变并且顶点数可以是 3 以上的任何数字。
如果有人不知道 Chaos Game 是什么,那么在该游戏中,您可以使用具有任意数量顶点的多边形。首先,您在多边形内放置一个点,随机选择一个顶点,然后在您刚才放置的点和随机选择的顶点之间的中间绘制一个新点。你一直重复这个过程,每次你都会使用新绘制的点。
在这个脚本中,我还包含了一个规则,以确保它不会连续两次选择相同的顶点来形成具有 3 个以上顶点的漂亮分形。 3个顶点实际上形成了谢尔宾斯基三角形。
这是 Numberphile 的 link 视频:https://www.youtube.com/watch?v=kbKtFN71Lfs
您可能会说,我对 Python 和一般的编码有些陌生。
完整代码:
import turtle as t
import tkinter as tk
from tkinter import ttk
from random import randint
wn = t.Screen()
wn.colormode(255)
t.pu();t.ht();t.speed(0)
plist = []
l = 0
val = 0
pb=ttk.Progressbar(orient="horizontal",length=wn.window_width(),mode="determinate")
pb.pack(side=tk.BOTTOM)
pb["value"]=0
def Clear():
t.clear()
plist = []
def Dot(x, y):
t.goto(x, y)
t.dot(5, (0, 0, 255))
plist.append(t.pos())
def Run(x, y):
wn.onscreenclick(None)
wn.tracer(0, 0)
l = len(plist)
pb["maximum"]=l*1000
xyc = randint(0, l-1)
xyc_old = 0
for _ in range(l*10):
xyc = randint(0, l-1)
for i in range(100):
xyc = randint(0, l-1);
if l >= 4:
while xyc == xyc_old:
xyc = randint(0, l-1);
xyc_old = xyc;
t.goto((t.pos()[0]+plist[xyc][0])/2, (t.pos()[1]+plist[xyc][1])/2);
t.dot(2, (255, 0, 0));
pb["value"]+=1;
pb.update()
wn.update()
plist.clear()
wn.onscreenclick(Dot, btn=1)
wn.onscreenclick(Run, btn=3)
wn.onscreenclick(Dot, btn=1)
wn.onscreenclick(Run, btn=3)
wn.onkey(Clear, "c")
wn.listen()
wn.mainloop()
我觉得我的编码风格与这里的很多人有很大不同,但我希望这不是问题。
谢谢!
I assume the large amount of dots is what causes the program to begin
running slower after a bit and I was wondering if anyone could help me
come up with a workaround for this.
令人惊讶的是,没有。是你自己的工具(进度条)拖慢了你的速度。注释掉:
pb.update()
看看会发生什么。
I feel like my coding style is very different from a lot of the people
on here, but I hope that isn't an issue.
这是一个与糟糕编码风格重叠的问题。例如。缺少白色 space、分号的使用、代码中的有效空操作等。我对您的代码进行了修改:
from turtle import Screen, Turtle
import tkinter as tk
from tkinter import ttk
from random import randrange
def clear():
turtle.clear()
plist.clear()
def dot(x, y):
turtle.goto(x, y)
turtle.dot(5, 'blue')
plist.append(turtle.position())
def run(x, y):
screen.onscreenclick(None, btn=1)
screen.onscreenclick(None, btn=3)
screen.onkey(None, 'c')
length = len(plist)
flag = length >= 4
pb['maximum'] = length * 1000
xyc_old = 0
for _ in range(length * 100):
for _ in range(10):
xyc = randrange(length)
if flag:
while xyc == xyc_old:
xyc = randrange(length)
xyc_old = xyc
x, y = turtle.position()
dx, dy = plist[xyc]
turtle.goto((x + dx) / 2, (y + dy) / 2)
turtle.dot(2)
pb['value'] += 10
pb.update()
plist.clear()
pb['value'] = 0
screen.onscreenclick(dot, btn=1)
screen.onscreenclick(run, btn=3)
screen.onkey(clear, 'c')
plist = []
screen = Screen()
screen.tracer(False)
turtle = Turtle()
turtle.hideturtle()
turtle.setundobuffer(None)
turtle.color('red')
turtle.penup()
pb = ttk.Progressbar(orient='horizontal', length=screen.window_width(), mode='determinate')
pb.pack(side=tk.BOTTOM)
pb['value'] = 0
screen.onscreenclick(dot, btn=1)
screen.onscreenclick(run, btn=3)
screen.onkey(clear, 'c')
screen.listen()
screen.mainloop()
其他变化包括:
如果没有 global plist
,Clear()
中的 plist = []
将无法工作。请改用 plist.clear()
。
您还需要在 Run
期间禁用(并重新启用)wn.onkey(Clear, "c")
,否则您的用户可能会破坏程序。您还需要单独禁用两个鼠标按钮。
你真的想要randrange()
,而不是randint()
。
我编写此脚本是为了使用 turtle 模块来复制我在 Numberphile 的频道上看到的混沌游戏。绘制了大量的点以使其在更大范围内运行良好。我假设大量的点是导致程序开始 运行 变慢的原因,我想知道是否有人可以帮我想出一个解决方法。
我愿意接受任何类型的解决方案,只要控件保持不变并且顶点数可以是 3 以上的任何数字。
如果有人不知道 Chaos Game 是什么,那么在该游戏中,您可以使用具有任意数量顶点的多边形。首先,您在多边形内放置一个点,随机选择一个顶点,然后在您刚才放置的点和随机选择的顶点之间的中间绘制一个新点。你一直重复这个过程,每次你都会使用新绘制的点。
在这个脚本中,我还包含了一个规则,以确保它不会连续两次选择相同的顶点来形成具有 3 个以上顶点的漂亮分形。 3个顶点实际上形成了谢尔宾斯基三角形。
这是 Numberphile 的 link 视频:https://www.youtube.com/watch?v=kbKtFN71Lfs
您可能会说,我对 Python 和一般的编码有些陌生。
完整代码:
import turtle as t
import tkinter as tk
from tkinter import ttk
from random import randint
wn = t.Screen()
wn.colormode(255)
t.pu();t.ht();t.speed(0)
plist = []
l = 0
val = 0
pb=ttk.Progressbar(orient="horizontal",length=wn.window_width(),mode="determinate")
pb.pack(side=tk.BOTTOM)
pb["value"]=0
def Clear():
t.clear()
plist = []
def Dot(x, y):
t.goto(x, y)
t.dot(5, (0, 0, 255))
plist.append(t.pos())
def Run(x, y):
wn.onscreenclick(None)
wn.tracer(0, 0)
l = len(plist)
pb["maximum"]=l*1000
xyc = randint(0, l-1)
xyc_old = 0
for _ in range(l*10):
xyc = randint(0, l-1)
for i in range(100):
xyc = randint(0, l-1);
if l >= 4:
while xyc == xyc_old:
xyc = randint(0, l-1);
xyc_old = xyc;
t.goto((t.pos()[0]+plist[xyc][0])/2, (t.pos()[1]+plist[xyc][1])/2);
t.dot(2, (255, 0, 0));
pb["value"]+=1;
pb.update()
wn.update()
plist.clear()
wn.onscreenclick(Dot, btn=1)
wn.onscreenclick(Run, btn=3)
wn.onscreenclick(Dot, btn=1)
wn.onscreenclick(Run, btn=3)
wn.onkey(Clear, "c")
wn.listen()
wn.mainloop()
我觉得我的编码风格与这里的很多人有很大不同,但我希望这不是问题。
谢谢!
I assume the large amount of dots is what causes the program to begin running slower after a bit and I was wondering if anyone could help me come up with a workaround for this.
令人惊讶的是,没有。是你自己的工具(进度条)拖慢了你的速度。注释掉:
pb.update()
看看会发生什么。
I feel like my coding style is very different from a lot of the people on here, but I hope that isn't an issue.
这是一个与糟糕编码风格重叠的问题。例如。缺少白色 space、分号的使用、代码中的有效空操作等。我对您的代码进行了修改:
from turtle import Screen, Turtle
import tkinter as tk
from tkinter import ttk
from random import randrange
def clear():
turtle.clear()
plist.clear()
def dot(x, y):
turtle.goto(x, y)
turtle.dot(5, 'blue')
plist.append(turtle.position())
def run(x, y):
screen.onscreenclick(None, btn=1)
screen.onscreenclick(None, btn=3)
screen.onkey(None, 'c')
length = len(plist)
flag = length >= 4
pb['maximum'] = length * 1000
xyc_old = 0
for _ in range(length * 100):
for _ in range(10):
xyc = randrange(length)
if flag:
while xyc == xyc_old:
xyc = randrange(length)
xyc_old = xyc
x, y = turtle.position()
dx, dy = plist[xyc]
turtle.goto((x + dx) / 2, (y + dy) / 2)
turtle.dot(2)
pb['value'] += 10
pb.update()
plist.clear()
pb['value'] = 0
screen.onscreenclick(dot, btn=1)
screen.onscreenclick(run, btn=3)
screen.onkey(clear, 'c')
plist = []
screen = Screen()
screen.tracer(False)
turtle = Turtle()
turtle.hideturtle()
turtle.setundobuffer(None)
turtle.color('red')
turtle.penup()
pb = ttk.Progressbar(orient='horizontal', length=screen.window_width(), mode='determinate')
pb.pack(side=tk.BOTTOM)
pb['value'] = 0
screen.onscreenclick(dot, btn=1)
screen.onscreenclick(run, btn=3)
screen.onkey(clear, 'c')
screen.listen()
screen.mainloop()
其他变化包括:
如果没有 global plist
,Clear()
中的 plist = []
将无法工作。请改用 plist.clear()
。
您还需要在 Run
期间禁用(并重新启用)wn.onkey(Clear, "c")
,否则您的用户可能会破坏程序。您还需要单独禁用两个鼠标按钮。
你真的想要randrange()
,而不是randint()
。