From b94b24ab0d7411cb7f26f2e671ba7ed7d6e99e41 Mon Sep 17 00:00:00 2001 From: Anthony Wang Date: Mon, 29 Jan 2024 13:52:22 -0500 Subject: Spread circles out evenly across path, move stuff to separate file --- script.js | 54 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'script.js') diff --git a/script.js b/script.js index d40711a..6cfcd78 100644 --- a/script.js +++ b/script.js @@ -6,14 +6,15 @@ document.querySelectorAll("svg").forEach(function(svg) { svg.outerHTML = req.responseText }) -let rad = 10 // Stroke width +let rad = 10 // Stroke radius let size = 200 // SVG width and height let A = [] // Objects let cnt = 0 document.querySelectorAll("svg").forEach(function(svg) { // Move objects so they aren't overlapping - svg.style.left = 1.5 * size * cnt++ + "px" - svg.style.top = "50px" + svg.style.left = 1.5 * size * (cnt % 2) + "px" + svg.style.top = 1.5 * size * Math.floor(cnt / 2) + "px" + cnt++ let a = { id: svg.id, // Unique ID p: [], // Collision circles @@ -25,8 +26,9 @@ document.querySelectorAll("svg").forEach(function(svg) { } svg.querySelectorAll("path").forEach(function(path) { // Get circles on path for collision checking - for (let i = 0; i < path.getTotalLength(); i += 5) { - const p = path.getPointAtLength(i) + let num = Math.floor(path.getTotalLength() / 5) + for (let i = 0; i <= num; i++) { + const p = path.getPointAtLength(i / num * path.getTotalLength()) a.cm.x += p.x a.cm.y += p.y a.p.push(p) @@ -34,7 +36,7 @@ document.querySelectorAll("svg").forEach(function(svg) { /* let circle = document.createElementNS("http://www.w3.org/2000/svg", "circle") circle.setAttribute("cx", p.x) circle.setAttribute("cy", p.y) - circle.setAttribute("r", rad) + circle.setAttribute("r", 10) circle.setAttribute("fill", "red") svg.appendChild(circle) */ } @@ -119,24 +121,31 @@ function wallCollide(a, k, d) { // Collision of object a with object b function objectsCollide(a, b) { - if (ds(a, b) < size * size) { + if (ds(a, b) < 2 * (size + 2 * rad) ** 2) { // Objects are close let c = {x: 0, y: 0, cnt: 0} let n = {x: 0, y: 0} + // Slight performance optimization? + // Only consider points close to other object + let aa = [] + let bb = [] for (const p of a.p.map(x => rot(a, x))) { - // p is close to object b - if (ds(p, b) < size * size) { - for (const q of b.p.map(x => rot(b, x))) { - const d = ds(p, q) - if (d < 4 * rad * rad) { - // Collision! - // These calculations are a bit sketchy but I guess they work? - c.x += p.x + q.x - c.y += p.y + q.y - c.cnt++ - n.x += (p.x - q.x) / d - n.y += (p.y - q.y) / d - } + if (ds(p, b) < 2 * (size + 2 * rad) ** 2) aa.push(p) + } + for (const p of b.p.map(x => rot(b, x))) { + if (ds(p, a) < 2 * (size + 2 * rad) ** 2) bb.push(p) + } + for (const p of aa) { + for (const q of bb) { + const d = ds(p, q) + if (d < (2 * rad) ** 2) { + // Collision! + // These calculations are a bit sketchy but I guess they work? + c.x += p.x + q.x + c.y += p.y + q.y + c.cnt++ + n.x += (p.x - q.x) / d + n.y += (p.y - q.y) / d } } } @@ -152,6 +161,7 @@ function objectsCollide(a, b) { } } +// Move stuff, check collisions, and render function tick() { // Move each object one step for (let a of A) { @@ -162,7 +172,6 @@ function tick() { if (Math.abs(a.vy) > 0.001) a.vy -= 0.001 * Math.sign(a.vy) if (Math.abs(a.w) > 0.00001) a.w -= 0.00001 * Math.sign(a.w) } - // Check wall collisions for (let a of A) { wallCollide(a, 0, 0) @@ -170,14 +179,12 @@ function tick() { wallCollide(a, 0, 1) wallCollide(a, window.innerHeight, 1) } - // Check collisions between objects for (let i = 0; i < A.length; i++) { for (let j = i + 1; j < A.length; j++) { objectsCollide(A[i], A[j]) } } - // Render every 10ms cnt++ if (cnt == 10) { @@ -198,7 +205,6 @@ function updatev(event) { a.vx += 100 * (a.x - event.clientX) / d a.vy += 100 * (a.y - event.clientY) / d } - // Display spreading out circles let circle = document.createElement("div") circle.style.width = circle.style.height = "10px" -- cgit v1.2.3-70-g09d2