Closest lines 🌐

Create x amount points in a grid or shape and add bit of offset to its place. Filter out all points that are in its near attraction distance range, draw lines between those.

```const turtle = new Turtle();
const total = 1000; // min=10, max=5000, step=1
const minDistance = 5; // min=1, max=50, step=1
const maxDistance = 15; // min=1, max=50, step=1
const distort = 2; // min=0, max=20, step=0.1
const shape = 1; // min=1, max=5, step=1 (Random, Columns, Grid, Spiral, Circles)
const random = new Random(shape + total + minDistance + maxDistance + distort * 10);
const opacity = 0.3; // min=0.01, max=1, step=0.01

Canvas.setpenopacity(opacity);

const points = Array.from({ length: total }, (_, idx) => {
const distance = random.range(minDistance, maxDistance);
switch (shape) {
case 1: {
return [random.range(-100, 100), random.range(-95, 95), distance];
}
case 2: {
return [Math.round(random.range(-10, 10)) * 10 + random.range(-distort, distort), random.range(-95, 95), distance];
}
case 3: {
return [Math.round(random.range(-10, 10)) * 10 + random.range(-distort, distort), Math.round(random.range(-10, 10)) * 10 + random.range(-distort, distort), distance];
}
case 4: {
let angle = Math.PI + (idx / total) * (Math.PI * 10);
if (distort) angle += random.range(20 / -distort, 20 / distort);
const a = 20;
const b = 2;
return [(a + b * angle) * Math.sin(angle) + random.range(-distort, distort), (a + b * angle) * Math.cos(angle) + random.range(-distort, distort), distance];
}
case 5: {
let angle = (idx / total) * (Math.PI * 2);
if (distort) angle += random.range(20 / -distort, 20 / distort);
const size = (random.range(2, 10) | 0) * 10;
return [size * Math.sin(angle) + random.range(-distort, distort), size * Math.cos(angle) + random.range(-distort, distort), distance];
}
}
});

function walk(idx) {
const point = points[idx];
const closePoints = points.filter((p) => (p[0] - point[0]) * (p[0] - point[0]) + (p[1] - point[1]) * (p[1] - point[1]) < point[2] * point[2]);
closePoints.forEach((p) => (turtle.jump(point), turtle.goto(p)));
return idx < points.length - 1;
}

// Seeded random - Mulberry32
function Random(seed) {
class Random {
constructor(seed) {
this.seed = seed;
}
next() {
var t = this.seed += 0x6D2B79F5;
t = Math.imul(t ^ t >>> 15, t | 1);
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
return ((t ^ t >>> 14) >>> 0) / 4294967296;
}
range(from, to) {
var r = this.next();
return from + (to - from) * r;
}
either(a = 0, b = 1, chance = 0.5) {
return this.next() > chance ? a : b;
}
shuffle(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(this.next() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}
}
return new Random(seed);
}
```