dynamic-system-dot-plot/script.js
Christian Lawson-Perfect bdbb9f81e0 first commit
2025-02-09 20:08:45 +00:00

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);