summaryrefslogtreecommitdiff
path: root/script.js
diff options
context:
space:
mode:
Diffstat (limited to 'script.js')
-rw-r--r--script.js54
1 files changed, 30 insertions, 24 deletions
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"