115 lines
2.9 KiB
Python
115 lines
2.9 KiB
Python
import svgwrite
|
|
import random
|
|
import time
|
|
from math import factorial
|
|
from itertools import permutations
|
|
import tsp as m_tsp
|
|
|
|
def dist(p1,p2):
|
|
return dist2(p1,p2)**0.5
|
|
|
|
|
|
def dist2(p1,p2):
|
|
diff=0
|
|
for a,b in zip(p1,p2):
|
|
diff+=(a-b)**2
|
|
return diff
|
|
|
|
|
|
def tsp(points):
|
|
res=[]
|
|
for idx in m_tsp.tsp(points)[1]:
|
|
res.append(points[idx])
|
|
return res
|
|
|
|
|
|
def make_points(n,size,min_dist=0):
|
|
min_dist*=min_dist
|
|
points=[]
|
|
while len(points)<n:
|
|
px,py=random.random(),random.random()
|
|
px*=size/2
|
|
py*=size/2
|
|
px+=70
|
|
py+=70
|
|
valid=True
|
|
for p in points:
|
|
if dist2(p,(px,py))<min_dist:
|
|
valid=False
|
|
break
|
|
if valid:
|
|
points.append((px,py))
|
|
print("{}/{}".format(len(points),n))
|
|
return points
|
|
def generate(seed,name=None,small=False):
|
|
sd=1
|
|
if small:
|
|
sd=2
|
|
random.seed(seed)
|
|
w=2
|
|
max_rings=3
|
|
num_points=10
|
|
min_dist=10+10+20*(max_rings+1)
|
|
base_r=10
|
|
ring_step=lambda v:10+v*10
|
|
size=1000
|
|
if name is None:
|
|
name=seed
|
|
dwg=svgwrite.Drawing(filename="out/{}.svg".format(name))
|
|
dwg.defs.add(dwg.style(".background { fill: #222; }"))
|
|
dwg.add(dwg.rect(size=('100%','100%'), class_='background'))
|
|
print("Generating points...")
|
|
color="#eee"
|
|
pos=make_points(num_points,size,min_dist=min_dist)
|
|
print("TSP...")
|
|
|
|
min_d=float('inf')
|
|
|
|
for p1 in pos:
|
|
for p2 in pos:
|
|
if p1==p2:
|
|
continue
|
|
min_d=min(min_d,dist(p1,p2))
|
|
print(min_d,min_dist)
|
|
pos=tsp(pos)
|
|
|
|
for (x1,y1),(x2,y2) in zip(pos,pos[1:]):
|
|
if small:
|
|
x1/=sd
|
|
x2/=sd
|
|
y1/=sd
|
|
y2/=sd
|
|
line=dwg.add(dwg.line((x1,y1),(x2,y2),stroke_width=w,stroke=color))
|
|
|
|
for (px,py) in pos:
|
|
base_r=3
|
|
if small:
|
|
base_r=5
|
|
px/=sd
|
|
py/=sd
|
|
px=svgwrite.px(px)
|
|
py=svgwrite.px(py)
|
|
if random.random()>0.8:
|
|
dwg.add(dwg.circle((px,py),r=base_r+random.random()*base_r,stroke_width=w,stroke='#0ae')).fill('#0ae')
|
|
else:
|
|
dwg.add(dwg.circle((px,py),r=base_r+random.random()*base_r,stroke_width=w,stroke=color)).fill(color)
|
|
r=base_r
|
|
for _ in range(random.randint(1,max_rings)):
|
|
if small:
|
|
random.random()
|
|
random.random()
|
|
continue
|
|
r+=ring_step(random.random())
|
|
if random.random()>0.75:
|
|
circ=dwg.add(dwg.circle((px,py),r=r,stroke_width=w,stroke="#ea0"))
|
|
else:
|
|
circ=dwg.add(dwg.circle((px,py),r=r,stroke_width=w,stroke=color))
|
|
circ.fill(color,opacity=0)
|
|
|
|
dwg.save()
|
|
|
|
|
|
|
|
seed=0
|
|
generate(seed,"icon_1",small=False)
|
|
generate(seed,"icon_1_small",small=True)
|