{
let height = 300;
let ctx = DOM.context2d(width, height);
const heightAmplifier = 100;
const segments = [];
const coils = 200;
const rotation = 0;
const thetaMax = coils * 2 * Math.PI;
const chord = 1;
const center = [width / 2, height * 1.5];
let radius = 400;
const step = radius / thetaMax;
let lastVertice;
for (let i = 0, theta = chord / step; theta <= thetaMax; i++) {
const away = step * theta;
const around = theta + rotation;
radius += 0.05;
let x = center[0] + Math.cos(around) * away;
let y = center[1] + Math.sin(around) * away;
let h = heightAt(x, y) * heightAmplifier;
x += Math.cos(around);
y += h + Math.sin(around);
if (i > 0 && y < height + 5) {
segments.push({
x0: lastVertice.x,
y0: lastVertice.y,
x: x,
y: y
});
}
lastVertice = { x, y, h };
theta += chord / away;
}
const minX = segments.reduce(
(acc, segment) => Math.min(acc, segment.x0),
Infinity
);
const maxX = segments.reduce(
(acc, segment) => Math.max(acc, segment.x0),
-Infinity
);
const minY = segments.reduce(
(acc, segment) => Math.min(acc, segment.y0),
Infinity
);
const maxY = segments.reduce(
(acc, segment) => Math.max(acc, segment.y0),
-Infinity
);
const layersX = [];
const range = (maxX - minX) * (_bucketSize / 10000);
console.log({
range,
maxX,
minX,
maxY,
minY
});
ctx.fillStyle = 'blue';
ctx.fillRect(minX, minY, range, range);
ctx.stroke();
segments.forEach(segment => {
const midX = (segment.x0 + segment.x) / 2;
const indexX = Math.round((midX - minX) * range);
if (!(indexX in layersX)) {
layersX[indexX] = [];
}
const midY = (segment.y0 + segment.y) / 2;
const indexY = Math.round((midY - minY) * range);
if (!(indexY in layersX[indexX])) {
layersX[indexX][indexY] = [];
}
layersX[indexX][indexY].push(segment);
});
layersX.forEach((layerX, x) => {
layerX.forEach((bucketXY, y) => {
const bucketsBelow = [...Array(10).keys()]
.map(i => layerX[y + i + 1])
.filter(Boolean);
if (bucketsBelow.length > 2) {
ctx.strokeStyle = 'green';
} else {
ctx.strokeStyle = 'black';
}
ctx.beginPath();
for (const segment of bucketXY) {
ctx.lineTo(segment.x0, segment.y0);
ctx.lineTo(segment.x, segment.y);
}
ctx.stroke();
});
});
return ctx.canvas;
}