95 lines
No EOL
2.2 KiB
JavaScript
95 lines
No EOL
2.2 KiB
JavaScript
const svg = document.querySelector('svg');
|
|
|
|
const d = ([x,y]) => {
|
|
const u = -0.3;
|
|
const s = -0.2;
|
|
const t = 0.1;
|
|
return [0.1-y*u+x*s, x*u+y*s + Math.sin(x*5)*t];
|
|
}
|
|
|
|
let all_points = [];
|
|
|
|
let num_path = 1;
|
|
|
|
function sqdist([x1,y1], [x2,y2]) {
|
|
return (x2-x1)**2 + (y2-y1)**2;
|
|
}
|
|
|
|
function element(name,attr,content) {
|
|
const e = document.createElementNS('http://www.w3.org/2000/svg',name);
|
|
if(attr) {
|
|
Object.entries(attr).forEach(([k,v])=>e.setAttribute(k,v));
|
|
}
|
|
if(content!==undefined) {
|
|
e.textContent = content;
|
|
}
|
|
return e;
|
|
}
|
|
|
|
function trace_path(pos, fn, h, steps) {
|
|
num_path += 1;
|
|
h = h || 0.01;
|
|
steps = steps || 1000;
|
|
const points = [];
|
|
for(let i=0;i<steps; i++) {
|
|
let [x,y] = pos;
|
|
let [dx,dy] = fn(pos);
|
|
if(is_occupied(pos, num_path)) {
|
|
break;
|
|
}
|
|
occupy(pos, num_path);
|
|
points.push(pos);
|
|
|
|
pos = [x+dx*h, y+dy*h];
|
|
}
|
|
return points;
|
|
}
|
|
|
|
function plot_path(pos, fn, h, steps) {
|
|
const points = trace_path(pos, fn, h, steps);
|
|
if(points.length < 5) {
|
|
return [];
|
|
}
|
|
const path = element('path', {d: `M ${points[0][0]} ${points[0][1]} ` + points.map(([x,y]) => `L ${x} ${y}`).join(' ')});
|
|
svg.append(path);
|
|
all_points = all_points.concat(points);
|
|
return points;
|
|
}
|
|
|
|
const occupied = [];
|
|
|
|
const bucket_size = 200;
|
|
function bucket_position([x,y]) {
|
|
const ix = Math.floor((x+2)/4*bucket_size);
|
|
const iy = Math.floor((y+2)/4*bucket_size);
|
|
return iy*bucket_size + ix;
|
|
}
|
|
|
|
function is_occupied(pos, n) {
|
|
const r = occupied[bucket_position(pos)];
|
|
return r && r!=n;
|
|
}
|
|
|
|
function occupy(pos, n) {
|
|
const i = bucket_position(pos);
|
|
occupied[i] = n;
|
|
const x = (i % bucket_size)/bucket_size;
|
|
const y = ((i - x) / bucket_size)/bucket_size;
|
|
console.log(pos, x,y);
|
|
const dot = element('circle', {r:1.5/bucket_size, fill: `hsl(${n*20}, 70%, 50%)`, cx: (x*4-2), cy: y*4-2, 'fill-opacity': 0.1});
|
|
svg.append(dot);
|
|
}
|
|
|
|
function randrange(a,b) {
|
|
return (b-a)*Math.random() + a;
|
|
}
|
|
|
|
for(let i=0;i<400; i++) {
|
|
const r = Math.sqrt(Math.random())*1.5;
|
|
const an = randrange(0, 2*Math.PI);
|
|
const pos = [r*Math.cos(an), r*Math.sin(an)];
|
|
plot_path(pos, d)
|
|
}
|
|
|
|
window.bucket_position = bucket_position;
|
|
console.log(occupied); |