paths = {
const board = d3.quadtree()
.x(d => d.x)
.y(d => d.y)
.extent([drawingExtent.x, drawingExtent.y])
const tooCloseToExistingPoint = (next, last) => {
const nearest = board.find(next.x, next.y, stepLength * minPointsProximity)
if (!nearest) { return false }
const isJustPrevious = nearest.x === last.x && nearest.y === last.y
return !isJustPrevious
}
const pathTracer = (init) => {
const result = []
result.push(init)
while (result.length < 100) {
const l = result[result.length - 1]
const p = fieldQuadTree.find(l.x, l.y)
let next = {
x: l.x + Math.cos(p.theta) * stepLength,
y: l.y + Math.sin(p.theta) * stepLength
}
const isTooClose = (result.length && tooCloseToExistingPoint(next, result[result.length - 1]))
result.push(next)
if (isTooClose || Math.random() > 0.98 || result.length > 35) { break; }
if (!isPointInsideOrnament(next, ornamentBoundaryLines)) {
break;
}
}
return result
}
const minPathLength = 4
const paths = []
let failureCount = 0
let acceptanceThreshold = 25
d3.range(30000).forEach((i) => {
const q = { x: Math.random() * drawingExtent.x[1], y: Math.random() * drawingExtent.y[1] }
if (!isPointInsideOrnament(q, exteriorLines) || getSideIDGivenPoint(q) === null) { return }
const path = pathTracer(q)
const keep = path.length > acceptanceThreshold
if (keep) {
board.addAll(path)
paths.push(path)
} else {
failureCount++
}
if (failureCount > 15) {
acceptanceThreshold = Math.max(3, acceptanceThreshold * 0.98)
failureCount = 0
}
})
return paths
}