Skip to content

Instantly share code, notes, and snippets.

@lpadukana
Last active June 5, 2021 00:04
Show Gist options
  • Select an option

  • Save lpadukana/0b4b679c43656ea3027fc7c22ef38d58 to your computer and use it in GitHub Desktop.

Select an option

Save lpadukana/0b4b679c43656ea3027fc7c22ef38d58 to your computer and use it in GitHub Desktop.
import math
import pathlib
import random
import cairosvg
import numpy
import svgwrite
def hsv_to_rgb(h, s, v):
i = math.floor(h * 6)
f = h * 6 - i
p = v * (1 - s)
q = v * (1 - f * s)
t = v * (1 - (1 - f) * s)
r, g, b = [
(v, t, p),
(q, v, p),
(p, v, t),
(p, q, v),
(t, p, v),
(v, p, q),
][int(i % 6)]
return r, g, b
def seamless_wires(dim=8192, init_angle=(-.1, .1, 2), turn_angle=(-45, 45, 2),
n_wires=200, n_seg=(4, 16, 10), seg_size=(100, 600, 3),
h=(0., 1., 10), s=(0., 1., 10), v=(0., 1., 10),
wire_width=(1., 4., 5), fname='out.svg', seed=0, scale=1,
stroke_linejoin='round', # arcs | bevel |miter | miter-clip | round
stroke_linecap='round'): # butt | round | square
def range_scale(tup, scale):
tup1 = tuple(x * scale for x in tup)
return tup1[:-1] + (int(tup[-1]),) # don't scale last element, which is the num steps for linspace
dim *= scale
seg_size = range_scale(seg_size, scale)
wire_width = range_scale(wire_width, scale)
random.seed(seed)
numpy.random.seed(seed)
dwg = svgwrite.Drawing(fname, (dim, dim), debug=True)
dwg.add(dwg.rect(
insert=(0, 0), size=('100%', '100%'),
rx=None, ry=None, fill='rgb(0,0,0)'
))
for _ in range(n_wires):
sw = random.choice(numpy.linspace(*wire_width))
_r, _g, _b = hsv_to_rgb(random.choice(numpy.linspace(*h)),
random.choice(numpy.linspace(*s)),
random.choice(numpy.linspace(*v)))
c = f'rgb({int(_r * 255)}, {int(_g * 255)}, {int(_b * 255)})'
lines = dwg.add(dwg.g(
stroke_width=sw,
stroke=c,
stroke_opacity=1.,
fill='none'))
x, y = numpy.random.randint(0, dim), numpy.random.randint(0, dim)
last = x, y
dths = [numpy.pi / 180 * a for a in numpy.linspace(*turn_angle)]
th = random.choice(dths) * random.randint(0, 350) + random.choice(numpy.linspace(*init_angle)) * numpy.pi / 180
points = []
segs = int(random.choice(numpy.linspace(*n_seg)))
for i in range(segs):
# dwg.add(dwg.text(f"{i}", insert=(x, y), font_size="20px", fill='black'))
points.append([x, y])
dr = random.choice(numpy.linspace(*seg_size))
x = x + dr * numpy.cos(th)
y = y + dr * numpy.sin(th)
if x < 0 or x > dim or y < 0 or y > dim:
points.append([x, y])
# finalize segment
lines.add(dwg.polyline(
points,
stroke_linejoin=stroke_linejoin,
stroke_linecap=stroke_linecap))
points = []
# start a new segment
lines = dwg.add(dwg.g(
stroke_width=sw,
stroke=c,
stroke_opacity=1,
fill='none'))
x0, y0 = last
x1, y1 = x, y
dx, dy = x1 - x0, y1 - y0
x0 = x1 % dim - dx * 4
y0 = y1 % dim - dy * 4
points.append([x0, y0])
x, y = x % dim, y % dim
points.append([x, y])
last = x, y
th += random.choice(dths)
lines.add(dwg.polyline(
points,
stroke_linejoin=stroke_linejoin,
stroke_linecap=stroke_linecap))
# dwg.save(pretty=True)
cairosvg.svg2png(bytestring=dwg.tostring(), write_to=fname + '.png')
def hex_mess_1():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
turn_angle=(-60, 60, 2),
h=(.001, .999, 100),
s=(0., 0., 100),
v=(.1, .65, 100),
n_wires=2000,
n_seg=(4, 16, 10),
seg_size=(100, 400, 3),
init_angle=(-5, 5, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
fname=f'out.svg',
wire_width=(5, 30., 10),
scale=.2,
# scale=1
)
for i in range(2):
seamless_wires(**{**kwargs, **dict(
s=(0, 1., 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_gray.svg')})
def hex_mess_2():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
turn_angle=(-60, 60, 2),
h=(.001, .1, 10),
s=(.5, 1., 10),
v=(.0, .7, 10),
n_wires=3000,
n_seg=(8, 10, 10),
seg_size=(50, 400, 2),
init_angle=(-5, 5, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
fname=f'out.svg',
wire_width=(5, 30., 10),
scale=.2,
# scale=1
)
for i in range(2):
seamless_wires(**{**kwargs, **dict(
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 10), v=(.0, 1., 10),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_gray.svg')})
def tris():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
turn_angle=(120, 120, 2),
h=(.001, .999, 100),
s=(0., 0., 100),
v=(.1, .65, 100),
n_wires=12000,
n_seg=(4, 4, 10),
seg_size=(100, 100, 3),
init_angle=(-0, 0, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
fname=f'out.svg',
wire_width=(4, 12., 10),
scale=.2,
# scale=1
)
for i in range(2):
seamless_wires(**{**kwargs, **dict(
s=(0, 1., 100),
init_angle=(-90 * i, 90 * i, 10),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 100),
init_angle=(-90 * i, 90 * i, 10),
fname=f'/tmp/out/{i}_gray.svg')})
def circles():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
turn_angle=(15, 15, 2),
h=(.7, .8, 100),
s=(0., 0., 100),
v=(.1, .65, 100),
n_wires=6000,
n_seg=(25, 25, 10),
seg_size=(40, 40, 2),
init_angle=(-0, 0, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
fname=f'out.svg',
wire_width=(4, 12., 10),
scale=.2,
# scale=1
)
for i in range(1):
seamless_wires(**{**kwargs, **dict(
s=(0, 1., 100),
init_angle=(-90 * i, 90 * i, 10),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 100),
init_angle=(-90 * i, 90 * i, 10),
fname=f'/tmp/out/{i}_gray.svg')})
def rusty_panels():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
init_angle=(-5, 5, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
turn_angle=(-45, 45, 2),
h=(.0, .1, 100), s=(0., 0., 100), v=(.1, .65, 100),
n_wires=2000, n_seg=(4, 16, 10), seg_size=(100, 400, 3),
wire_width=(5, 30., 10),
fname=f'out.svg',
scale=.2,
# scale=1
)
for i in range(2):
seamless_wires(**{**kwargs, **dict(
s=(0, 1., 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_gray.svg')})
def grass():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
init_angle=(-5, 5, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
turn_angle=(-25, 25, 10),
h=(.2, .3, 20), s=(0., 0., 20), v=(.05, .7, 20),
n_wires=10000, n_seg=(3, 6, 4), seg_size=(20, 180, 10),
wire_width=(5, 30., 10),
fname=f'out.svg',
scale=.2,
# scale=1
)
for i in range(2):
seamless_wires(**{**kwargs, **dict(
s=(0, 1., 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_gray.svg')})
def vines():
pathlib.Path("/tmp/out").mkdir(parents=True, exist_ok=True)
kwargs = dict(
dim=8192,
init_angle=(-35, 35, 2),
# init_angle=(-2, 2, 2),
# init_angle=(0, 0, 2),
turn_angle=(-25, 25, 10),
h=(.2, .3, 100), s=(0., 0., 100), v=(.1, .6, 100),
n_wires=500, n_seg=(40, 160, 10), seg_size=(60, 60, 2),
wire_width=(5, 30., 10),
fname=f'out.svg',
scale=.2
)
for i in range(1):
seamless_wires(**{**kwargs, **dict(
s=(.1, .8, 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_col.svg')})
seamless_wires(**{**kwargs, **dict(
s=(0., 0., 100), v=(.1, .9, 100),
init_angle=(-5 * i, 5 * i, 2),
fname=f'/tmp/out/{i}_gray.svg')})
if __name__ == '__main__':
# hex_mess_1()
# hex_mess_2()
# rusty_panels()
# grass()
vines()
# tris()
# circles()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment