// SINE-WAVE MESH — generate point paths, then resample and sew each one.
let nwaves  = 15      // [3:16]
let amp     = 15     // [6:24]   peak amplitude at the centre
let halfW   = 39     // [20:46]  half-length of the horizontal line
let baseCyc = 2      // [1:9]    base number of cycles
let cycVar  = 1    // [0:5]    frequency spread across the waves
let xJitter = 3      // [0:10]   how far each wave's start shifts
let slen    = 1    // [1:4]    stitch length

// @preset Calm       : nwaves=5, amp=12, cycVar=1.5, xJitter=3
// @preset Dense Mesh : nwaves=14, amp=18, cycVar=4, xJitter=6

seed 6
stitchlen slen

// half-sine envelope: 0 at both ends, 1 in the middle
def envelope(t) [
  return sin(t * 180)
]

// one swelling sine wave, as a list of points along the line
def buildwave(ox, cyc, phase) [
  let pts = []
  let n = 120
  for i = 0 to n [
    let t = i / n
    let x = ox - halfW + t * 2 * halfW
    let y = amp * envelope(t) * sin(t * cyc * 360 + phase)
    append(pts, [x, y])
  ]
  return pts
]

repeat nwaves [
  // `repcount` is 1-based; convert it to a zero-based index for calculations.
  let k     = repcount - 1
  let ox    = random(2 * xJitter) - xJitter          // different start position
  let cyc   = baseCyc + k * cycVar / nwaves + random(1)   // different frequency
  let phase = random(360)                            // different phase
  color((k % 3) + 2)
  up setpos([ox - halfW, 0]) down
  // The generated points are dense; resample makes their stitch spacing regular.
  sewpath(resample(buildwave(ox, cyc, phase), slen))
  trim
]
