paths = {
const board = d3.quadtree()
.x(d => d.x)
.y(d => d.y)
.extent([diameter, heightInMM])
const tooCloseToExistingPoint = (next) => {
const proximity = dynamicProximity(next)
const nearest = board.find(next.x, next.y, proximity)
return (!nearest) ? false : true
}
const pathTracer = (init) => {
const result = []
result.push(init)
while (result.length < 100) {
const l = result[result.length - 1]
const fp = fieldQuadTree.find(l.x, l.y)
let next = {
x: l.x + Math.cos(fp.radian) * stepLength,
y: l.y + Math.sin(fp.radian) * stepLength
}
const isTooClose = (result.length && tooCloseToExistingPoint(next))
result.push(next)
if (isTooClose || Math.random() > 0.98 || result.length > maxLength) { break; }
if (!isPointInBounds(next)) {
break;
}
}
return result
}
const minPathLength = 4
const paths = []
let failureCount = 0
let acceptanceThreshold = 75
d3.range(300000).forEach((i) => {
const q = { x: Math.random() * diameter, y: Math.random() * heightInMM }
if (!isPointInBounds(q)) { return }
const path = pathTracer(q)
const keep = path.length > acceptanceThreshold
if (keep) {
board.addAll(path)
paths.push(path)
} else {
failureCount++
}
if (failureCount > 25) {
acceptanceThreshold = Math.max(3, acceptanceThreshold * 0.98)
failureCount = 0
}
})
return paths
}