2017-08-29 14 views
0

Sierpinskyの三角形(モジュロの)をプロットするプログラムを作りたいと思います。これを行うために私はTkInterを使いました。プログラムは点をランダムに移動させてフラクタルを生成し、常にその点を側面に保持します。このプロセスを何度も繰り返した後、フラクタルが現れます。TkInter python - Sierpinskyの三角形を得るためのキャンバス上の点の作成

ただし、問題があります。私はTkInterのキャンバスにポイントをプロットする方法を知らない。プログラムの残りの部分はOKですが、ポイントの代わりに小さな線を描いてポイントをプロットするためには "チート"しなければなりませんでした。多かれ少なかれ動作しますが、可能な限り多くの解決策はありません。

キャンバス上にポイントをプロットする機能や、それを行う別のツール(Pythonを使用)がありますか?プログラムの残りの部分を改善するためのアイデアも歓迎します。

ありがとうございました。

from tkinter import * 
import random 
import math 
def plotpoint(x, y): 
    global canvas 
    point = canvas.create_line(x-1, y-1, x+1, y+1, fill = "#000000") 
x = 0 #Initial coordinates 
y = 0 
#x and y will always be in the interval [0, 1] 
mod = int(input("What is the modulo of the Sierpinsky triangle that you want to generate? ")) 
points = int(input("How many points do you want the triangle to have? ")) 
tkengine = Tk() #Window in which the triangle will be generated 
window = Frame(tkengine) 
window.pack() 
canvas = Canvas(window, height = 700, width = 808, bg = "#FFFFFF") #The dimensions of the canvas make the triangle look equilateral 
canvas.pack() 
for t in range(points): 
    #Procedure for placing the points 
    while True: 
     #First, randomly choose one of the mod(mod+1)/2 triangles of the first step. a and b are two vectors which point to the chosen triangle. a goes one triangle to the right and b one up-right. The algorithm gives the same probability to every triangle, although it's not efficient. 
     a = random.randint(0,mod-1) 
     b = random.randint(0,mod-1) 
     if a + b < mod: 
      break 
    #The previous point is dilated towards the origin of coordinates so that the big triangle of step 0 becomes the small one at the bottom-left of step one (divide by modulus). Then the vectors are added in order to move the point to the same place in another triangle. 
    x = x/mod + a/mod + b/2/mod 
    y = y/mod + b/mod 
    #Coordinates [0,1] converted to pixels, for plotting in the canvas. 
    X = math.floor(x * 808) 
    Y = math.floor((1-y) * 700) 
    plotpoint(X, Y) 
tkengine.mainloop() 

答えて

1

ピクセルをプロットする場合は、おそらくキャンバスが間違った選択です。 PhotoImageを作成し、個々のピクセルを変更することができます。個々のピクセルをプロットすると少し遅くなりますが、putメソッドをイメージの各行に対して1回だけ呼び出すと、劇的なスピードアップを得ることができます。

はここで完全な例です:本当に2ピクセル×2ピクセルの正方形であることやっによって生成された楕円:

from tkinter import * 
import random 
import math 

def plotpoint(x, y): 
    global the_image 
    the_image.put(('#000000',), to=(x,y)) 

x = 0 
y = 0 
mod = 3 
points = 100000 
tkengine = Tk() #Window in which the triangle will be generated 
window = Frame(tkengine) 
window.pack() 
the_image = PhotoImage(width=809, height=700) 
label = Label(window, image=the_image, borderwidth=2, relief="raised") 
label.pack(fill="both", expand=True) 

for t in range(points): 
    while True: 
     a = random.randint(0,mod-1) 
     b = random.randint(0,mod-1) 
     if a + b < mod: 
      break 
    x = x/mod + a/mod + b/2/mod 
    y = y/mod + b/mod 

    X = math.floor(x * 808) 
    Y = math.floor((1-y) * 700) 
    plotpoint(X, Y) 

tkengine.mainloop() 
+0

「イメージの各行に対してputメソッドを1回だけ呼び出すと、劇的なスピードアップが得られます。 –

+0

@MartínGómez私は、データの1ピクセルで 'put'を100回呼び出すことは、データの100ピクセルで' put'を1回呼び出すよりもかなり遅いことを意味します。 –

0

あなたはバウンディングボックスの二隅のために同じ座標を持つcanvas.create_ovalを使用することができます:ここに私が持っているものだ

from tkinter import * 
import random 
import math 
def plotpoint(x, y): 
    global canvas 
#  point = canvas.create_line(x-1, y-1, x+1, y+1, fill = "#000000") 
    point = canvas.create_oval(x, y, x, y, fill="#000000", outline="#000000") 
x = 0 #Initial coordinates 
y = 0 
#x and y will always be in the interval [0, 1] 
mod = int(input("What is the modulo of the Sierpinsky triangle that you want to generate? ")) 
points = int(input("How many points do you want the triangle to have? ")) 
tkengine = Tk() #Window in which the triangle will be generated 
window = Frame(tkengine) 
window.pack() 
canvas = Canvas(window, height = 700, width = 808, bg = "#FFFFFF") #The dimensions of the canvas make the triangle look equilateral 
canvas.pack() 
for t in range(points): 
    #Procedure for placing the points 
    while True: 
     #First, randomly choose one of the mod(mod+1)/2 triangles of the first step. a and b are two vectors which point to the chosen triangle. a goes one triangle to the right and b one up-right. The algorithm gives the same probability to every triangle, although it's not efficient. 
     a = random.randint(0,mod-1) 
     b = random.randint(0,mod-1) 
     if a + b < mod: 
      break 
    #The previous point is dilated towards the origin of coordinates so that the big triangle of step 0 becomes the small one at the bottom-left of step one (divide by modulus). Then the vectors are added in order to move the point to the same place in another triangle. 
    x = x/mod + a/mod + b/2/mod 
    y = y/mod + b/mod 
    #Coordinates [0,1] converted to pixels, for plotting in the canvas. 
    X = math.floor(x * 808) 
    Y = math.floor((1-y) * 700) 
    plotpoint(X, Y) 
tkengine.mainloop() 

3つの10万ポイントの深さに、これは与える:

enter image description here

+1

このソリューションは、別の問題があります。ピクセルを作る方法はないようです。 –

+0

IDKでは、(x、y、x、y)の境界ボックス内の "円"は、Mac(網膜ではない)LCDディスプレイで1x1のように見えますが、 、y + 1)BBはもっと大きく見えました...おそらくそれはシステムに依存しますか? –

0

最後に解決策を見つけた:1x1のポイントは画素(x、y)は、それ電子ないコマンド内に配置される場合xactlyは次のとおりです。

point = canvas.create_line(x, y, x+1, y+1, fill = "colour")

楕円形は2x2のポイントのために良いアイデアです。

元のプログラムで注目すべき点は、すべての点が別個のオブジェクトとして扱われる場合、多くのRAMを使用することです。

関連する問題