lsh-LineWalk


As I worked on these, I began to think of them as pinwheels. Getting the right “flutter” out was a challenge, and I also had a bug for a little where content ended up mostly off the page. I ended up trying to “weave” in the iteration by flipping whether I add or subtract it in the simplex noise for the x or y.

const Simplex = require("https://unpkg.com/simplex-noise@2.4.0/simplex-noise.js");
const simplex = new Simplex();
const width = 761;
const height = width;
// source: https://rosettacode.org/wiki/Map_range#ES6
const rangeMap = (a, b) => (s) => {
  const [a1, a2] = a;
  const [b1, b2] = b;
  // Scaling up an order, and then down, to bypass a potential,
  // precision issue with negative numbers.
  return ((((b2 - b1) * (s - a1)) / (a2 - a1)) * 10 + 10 * b1) / 10;
}

function generatePaths() {
  const start = [Math.random() * width, Math.random() * height];
  const step = 200.0;
  const path = [start];
  for (let i = 0; i < 100; i++) {
    const [px, py] = path.at(-1);
    const theta = simplex.noise2D(px * px * 10 * +i * i, py * py * 10 - i * i);
    const t = rangeMap([-1, 1], [-Math.PI, Math.PI])(theta);
    const x =
      Math.cos(t) * step + simplex.noise2D(px + i, py - i) * 100 + width / 2;
    const y =
      Math.sin(t) * step + simplex.noise2D(px - i, py + i) * 100 + height / 2;
    path.push([x, y]);
  }
  return path;
}

function draw() {
  const svg = d3.create("svg").attr("width", width).attr("height", height);
  svg
    .append("path")
    .attr("d", d3.line()(generatePaths()))
    .attr("fill", "none")
    .attr("stroke", "black");
  return svg.node();
}