svg`<svg width="${w}" height="${h}">
<rect width="${w}" height="${h}" stroke="blue" fill="none" />
<g>
${(() => {
const m = 36
const segments = array(m).map(i => PVector(w/2 + Math.cos(TAU / m * i) * h / 2, h/2 + Math.sin(TAU / m * i) * h / 2)).map((d, i, arr) => new Segment(d, arr[(i + 1) % arr.length]))
array(n).forEach(i => {
const pos = PVector(w/2, h/2).add(PVector.random2D().setMag(random(h / 2 - 5)))
const angle = random() < .8 ? randInt(4) * Math.PI / 4 : random(Math.PI)
const dir = PVector.fromAngle(angle).setMag(h+w)
const segment = new Segment(pos.clone().add(dir), pos.clone().sub(dir))
const intersections = []
for (const s of segments) {
const intersection = segSegIntersection(segment, s)
if (intersection !== null) intersections.push(intersection)
}
if(intersections.length > 0) {
intersections.sort((a, b) => a.distSq(segment.center) > b.distSq(segment.center) ? 1 : -1)
const nearest = getNearestIntersections(segment, intersections)
if(nearest !== null) segments.push(new Segment(nearest[0], nearest[1]))
}
})
return segments.map((s, i) => i < m ? '' : `<line
stroke="black"
x1="${s.a.x}" y1="${s.a.y}"
x2="${s.b.x}" y2="${s.b.y}"
/>
`).join('\n')
})()}
</g>
</svg>`