# -*- coding: utf-8 -*- import svgwrite import svgpathtools import random import tempfile import os from math import sin, cos, pi 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 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 ring_step(v): return 10 + v * 10 def generate(seed, name=None, small=False): sd = 1 if small: sd = 2 random.seed(seed) w = 2 max_rings = 3 num_points = 5 min_dist = 10 + 10 + 20 * (max_rings + 1) base_r = 10 size = 1000 if name is None: name = seed out_path = "out/{}.svg".format(name) dwg = svgwrite.Drawing(filename=out_path) dwg.defs.add(dwg.style(".background { fill: #222 }")) print("Generating points...") color = "#eee" pos = make_points(num_points, size, min_dist=min_dist) print("TSP...") pos = tsp(pos) for (x1, y1), (x2, y2) in zip(pos, pos[1:]): if small: x1 /= sd x2 /= sd y1 /= sd y2 /= sd 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 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() random.random() random.random() continue r += ring_step(random.random()) ring_col = color if random.random() > 0.75: ring_col = "#ea0" circ = dwg.add(dwg.circle((px, py), r=r, stroke_width=w, stroke=ring_col)) circ.fill(color, opacity=0) d = random.random() * pi * 2 dx = cos(d) dy = sin(d) m = random.random() moon = dwg.add( dwg.circle( (px + dx * r, py + dy * r), r=2 + 2 * m, stroke_width=w, stroke=ring_col, ) ) moon.fill(ring_col) dwg.fit() path = tempfile.TemporaryDirectory() filename = os.path.join(path.name, "out.svg") dwg.saveas(filename) paths, attrs = svgpathtools.svg2paths(filename) bbox = [float("inf"), float("-inf"), float("inf"), float("-inf")] for path in paths: path_bbox = path.bbox() bbox[0] = min(bbox[0], path_bbox[0]) # xmin bbox[1] = max(bbox[1], path_bbox[1]) # xmax bbox[2] = min(bbox[2], path_bbox[2]) # ymin bbox[3] = max(bbox[3], path_bbox[3]) # ymax px = bbox[0] sx = (bbox[1] - bbox[0]) py = bbox[2] sy = (bbox[3] - bbox[2]) dwg.add(dwg.rect(x=px, y=px, size=(sx, sy), class_="background")) dwg.elements.insert(1, dwg.elements.pop(-1)) dwg.saveas(out_path) seed = -5 generate(seed, "icon_1", small=False) generate(seed, "icon_1_small", small=True)