Continuing my practice of trying new tools for this course, I decided to try out the thing umbrella for this project. The umbrella is a project by Karsten Schmidt in which he creates a giant package ecosystem full of every algorithm one could ever want. Thi.ng was originally written in Clojure, and the transform definitely feels like Clojure. For instance, I spent a long time fighting with the system until I realized certain functions fail unless passed empty lists as a final parameter. That being said, the library is wildly powerful! I was able to achieve amazing results with very little code. I would totally use the thingiverse again, though maybe when under a much longer deadline. I found myself thinking of Good Shape while I worked—how it’s particularly difficult to describe what makes a shape “better.”
import { quad, asSvg, withAttribs, path } from '@thi.ng/geom'; import { star } from '@thi.ng/geom/ctors/polygon'; import { vertices } from '@thi.ng/geom/ops/vertices'; import { scatter } from '@thi.ng/geom/ops/scatter'; import { fuzzyPoly, compFill } from '@thi.ng/geom-fuzz'; import { svg } from '@thi.ng/hiccup-svg'; import { serialize } from '@thi.ng/hiccup'; import { shuffle } from '@thi.ng/arrays'; const width = 648; const height = 864; const buffer = 20; const rad = 45; const s = scatter( quad( [buffer + rad, buffer + rad], [width - buffer - rad, height - buffer - rad], [width - buffer - rad, height - buffer - rad], [0, height - buffer - rad], ), 17, ); const blobShapes = s.flatMap(([x, y], i) => Array.from({ length: i % 2 ? 6 : 1 }, (_) => star( rad + buffer * Math.random(), ~~(Math.random() * 5) + 3, [1.0, 1.5], { fill: 'none', stroke: 'black', 'stroke-width': '1px', transform: `translate(${x},${y}) scale(${i / s.length})`, }, ), ), ); const blobs = blobShapes .map((s) => fuzzyPoly(vertices(s), s.attribs, { jitter: 5, curveScale: 0.5 }), ) .map((b) => withAttribs(b.children.at(0), b.attribs)); const scene = asSvg(...blobs); const output = serialize(svg({ width, height }, scene)); document.querySelector('#app').innerHTML = `${output}`;