Skip to content

Instantly share code, notes, and snippets.

@azylinski
Last active June 24, 2020 07:21
Show Gist options
  • Save azylinski/49d3fc16333870db914c438dbbcba31a to your computer and use it in GitHub Desktop.
Save azylinski/49d3fc16333870db914c438dbbcba31a to your computer and use it in GitHub Desktop.
import svgwrite
from dataclasses import dataclass
from random import randint, uniform
@dataclass
class Circle:
x: float
y: float
r: float
@property
def center(self) -> tuple:
return (self.x, self.y)
def intersect(self, c:Circle) -> bool:
return (self.r + c.r)**2 >= (self.x - c.x)**2 + (self.y - c.y)**2
R = 200
SYMBOLS = 8
OPENMOJI_URL = 'https://openmoji.org/data/color/svg/'
CODES = ['1F98A', '1F984', '1F986', '1F34E', '1F349', '1F43C', '1F454', '1F4BE']
def rand_angle():
return randint(0, 360)
def inside(c):
return (R-c.x)**2 + (R-c.y)**2 <= (R-c.r)**2
def ratio():
return R * uniform(0.2, 0.35)
def rand_circle():
c = Circle(x=uniform(0, 2*R), y=uniform(0, 2*R), r=ratio())
if not inside(c):
return rand_circle()
return c
def circle_packing(n):
tmp = []
while len(tmp) < n:
c = rand_circle()
i = 0
while i < len(tmp):
x = tmp[i]
if c.intersect(x):
tmp[i] = tmp[-1]
del tmp[-1]
else:
i += 1
tmp.append(c)
return tmp
circles = circle_packing(SYMBOLS)
dwg = svgwrite.Drawing('out.svg', profile='tiny')
dwg.add(dwg.circle(center=(R, R), r=R))
shapes = dwg.add(dwg.g(id='shapes', fill='red'))
for c in circles:
shapes.add(svgwrite.shapes.Circle(c.center, c.r))
emojis = dwg.add(dwg.g(id='emojis'))
for it in range(SYMBOLS):
c = circles[it]
url = OPENMOJI_URL + CODES[it] + '.svg'
img = svgwrite.image.Image(url, insert=(c.x-c.r, c.y-c.r), size=(2*c.r, 2*c.r))
img.rotate(rand_angle(), c.center)
emojis.add(img)
dwg.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment