47 lines
1.5 KiB
Python
Executable File
47 lines
1.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
from __future__ import division
|
|
try:
|
|
import tkinter as tk
|
|
except:
|
|
import Tkinter as tk
|
|
import math
|
|
|
|
C = math.sqrt( 3 )
|
|
|
|
def koch( x, y, r, smin, nmax=None ):
|
|
pts, tmp = [ ( x, y + r ),
|
|
( x - C * r / 2, y - r / 2 ),
|
|
( x + C * r / 2, y - r / 2 ) ], []
|
|
s, n = 3 * r / C, 0
|
|
while s > smin and ( nmax is None or n < nmax ):
|
|
for i in range( len( pts ) ):
|
|
( x1, y1 ), ( x5, y5 ) = pts[ i - 1 ], pts[ i ]
|
|
dx, dy = ( x5 - x1 ) / 3, ( y5 - y1 ) / 3
|
|
tmp += [ ( x1 + dx, y1 + dy ),
|
|
( ( x1 + x5 + C * dy ) / 2, ( y1 + y5 - C * dx ) / 2 ),
|
|
( x5 - dx, y5 - dy ),
|
|
( x5, y5 ) ]
|
|
pts, tmp = tmp, []
|
|
s /= 4
|
|
n += 1
|
|
return pts, s, n
|
|
|
|
def redraw( data ):
|
|
x, y = data.width / 2, data.height / 2
|
|
r = min( 2 * x / C, y )
|
|
pts, s, n = koch( x, y, r, 4, None )
|
|
text = "#={}\ns={:.3f}\nn={}".format( len( pts ), s, n )
|
|
data.widget.delete( tk.ALL )
|
|
data.widget.create_oval( x - r, y - r, x + r, y + r, outline="#F88" )
|
|
data.widget.create_text( x, y, text=text, fill="#88F", justify=tk.CENTER )
|
|
for i in range( len( pts ) ):
|
|
( x1, y1 ), ( x2, y2 ) = pts[ i - 1 ], pts[ i ]
|
|
data.widget.create_line( x1, y1, x2, y2 )
|
|
|
|
window = tk.Tk()
|
|
window.title( "Koch" )
|
|
canvas = tk.Canvas( window )
|
|
canvas.pack( expand=True, fill=tk.BOTH )
|
|
canvas.bind( "<Configure>", redraw )
|
|
window.mainloop() |