Ungolfed「リファレンス実装」、Python
更新:はるかに高速(桁違い)
インタラクティブシェルをご覧ください!
ファイルを編集してに設定interactive
しTrue
、次のいずれかを実行します。
polygon numberOfPoints numeratorOfWeight denominatorOfWeight startX startY numberOfSides
ポリゴンを生成、保存、表示します。
points numberOfPoints numeratorOfWeight denominatorOfWeight startX startY point1X point1Y point2X point2Y ...
仕様が要求することを行います。
import matplotlib.pyplot as plt
import numpy as np
from fractions import Fraction as F
import random
from matplotlib.colors import ColorConverter
from time import sleep
import math
import sys
import cmd
import time
def plot_saved(n, r, start, points, filetype='png', barsize=30, dpi=100, poly=True, show=False):
printed_len = 0
plt.figure(figsize=(6,6))
plt.axis('off')
start_time = time.clock()
f = F.from_float(r).limit_denominator()
spts = []
for i in range(len(points)):
spts.append(tuple([round(points[i].real,1), round(points[i].imag,1)]))
if poly:
s = "{}-gon ({}, r = {}|{})".format(len(points), n, f.numerator, f.denominator)
else:
s = "{} ({}, r = {}|{})".format(spts, n, f.numerator, f.denominator)
step = math.floor(n / 50)
for i in range(len(points)):
plt.scatter(points[i].real, points[i].imag, color='#ff2222', s=50, alpha=0.7)
point = start
t = time.clock()
xs = []
ys = []
for i in range(n+1):
elapsed = time.clock() - t
#Extrapolation
eta = (n+1-i)*(elapsed/(i+1))
printed_len = rewrite("{:>29}: {} of {} ({:.3f}%) ETA: {:.3f}s".format(
s, i, n, i*100/n, eta), printed_len)
xs.append(point.real)
ys.append(point.imag)
point = point * r + random.choice(points) * (1 - r)
printed_len = rewrite("{:>29}: plotting...".format(s), printed_len)
plt.scatter(xs, ys, s=0.5, marker=',', alpha=0.3)
presave = time.clock()
printed_len = rewrite("{:>29}: saving...".format(s), printed_len)
plt.savefig(s + "." + filetype, bbox_inches='tight', dpi=dpi)
postsave = time.clock()
printed_len = rewrite("{:>29}: done in {:.3f}s (save took {:.3f}s)".format(
s, postsave - start_time, postsave - presave),
printed_len)
if show:
plt.show()
print()
plt.clf()
def rewrite(s, prev):
spaces = prev - len(s)
sys.stdout.write('\r')
sys.stdout.write(s + ' '*(0 if spaces < 0 else spaces))
sys.stdout.flush()
return len(s)
class InteractiveChaosGame(cmd.Cmd):
def do_polygon(self, args):
(n, num, den, sx, sy, deg) = map(int, args.split())
plot_saved(n, (num + 0.0)/den, np.complex(sx, sy), list(np.roots([1] + [0]*(deg - 1) + [-1])), show=True)
def do_points(self, args):
l = list(map(int, args.split()))
(n, num, den, sx, sy) = tuple(l[:5])
l = l[5:]
points = []
for i in range(len(l)//2):
points.append(complex(*tuple([l[2*i], l[2*i + 1]])))
plot_saved(n, (num + 0.0)/den, np.complex(sx, sy), points, poly=False, show=True)
def do_pointsdpi(self, args):
l = list(map(int, args.split()))
(dpi, n, num, den, sx, sy) = tuple(l[:6])
l = l[6:]
points = []
for i in range(len(l)//2):
points.append(complex(*tuple([l[2*i], l[2*i + 1]])))
plot_saved(n, (num + 0.0)/den, np.complex(sx, sy), points, poly=False, show=True, dpi=dpi)
def do_default(self, args):
do_generate(self, args)
def do_EOF(self):
return True
if __name__ == '__main__':
interactive = False
if interactive:
i = InteractiveChaosGame()
i.prompt = ": "
i.completekey='tab'
i.cmdloop()
else:
rs = [1/2, 1/3, 2/3, 3/8, 5/8, 5/6, 9/10]
for i in range(3, 15):
for r in rs:
plot_saved(20000, r, np.complex(0,0),
list(np.roots([1] + [0] * (i - 1) + [-1])),
filetype='png', dpi=300)