From c9b7c62365337e3cd6390b7a97aff72321ac48ff Mon Sep 17 00:00:00 2001 From: Catalin Constantin Mititiuc Date: Fri, 26 Dec 2025 11:20:29 -0800 Subject: [PATCH] WIP: don't overlap wall on collision --- html/images/space.svg | 144 ++++++++++++++++++++++++++++-------------- 1 file changed, 98 insertions(+), 46 deletions(-) diff --git a/html/images/space.svg b/html/images/space.svg index dbe1bb4..aa7ba44 100644 --- a/html/images/space.svg +++ b/html/images/space.svg @@ -63,8 +63,12 @@ display: none; } - line { - stroke: red; + line:not(#cannon) { + stroke: green; + } + + .wall { + opacity: 0.5; } .wall.inverse { @@ -86,7 +90,8 @@ - + + @@ -438,6 +443,7 @@ el.setAttribute('x2', xb); el.setAttribute('y2', yb); svg.appendChild(el); + return el; } function slope({ xa, ya, xb, yb }) { @@ -450,50 +456,20 @@ return Object.is(slope(edge), +0); } - // i need to know the point of collision to position the ship adjacent to it - function detectEdgeCollision([xc, yc], edge, { xa, ya, xb, yb }) { + function detectEdgeCollision([xc, yc], { xa, ya, xb, yb }) { const shipRadius = 5; - // const [[xa, ya], [xb, yb]] = edge.split(' ').map(n => n.split(',').map(n => +n)); const da = distance(xa, ya, xc, yc); const db = distance(xb, yb, xc, yc); // TODO: calculate this one ahead of time const dc = distance(xa, ya, xb, yb); - const baseSlope = slope({ xa, ya, xb, yb }); - - // console.log("slope of base", baseSlope); - - if (baseSlope === -Infinity) { - // console.log("foot", xa + shipRadius, yc); - } else if (baseSlope === Infinity) { - // console.log("foot", xa - shipRadius, yc); - } else if (Object.is(baseSlope, 0)) { - // console.log("foot", xc, ya - shipRadius); - } else if (Object.is(baseSlope, -0)) { - // console.log("foot", xc, ya + shipRadius); - } else { - const foot = perpIntxn(baseSlope, xa, ya, xc, yc); - // console.log("foot", foot); - // drawLine(foot.x, foot.y, xc, yc) - const el = document.createElementNS(namespaceURIsvg, 'line'); - el.setAttribute('x1', foot.x); - el.setAttribute('y1', foot.y); - el.setAttribute('x2', xc); - el.setAttribute('y2', yc); - // this point should be the position of the ship to make it - // adjacent to the collision edge without overlapping it - console.log(el.getPointAtLength(5)); - } - // https://en.wikipedia.org/wiki/Altitude_(triangle)#Altitude_in_terms_of_the_sides // Find altitude of side c (the base) const s = (1 / 2) * (da + db + dc); const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc)); return +hc.toFixed(2) <= shipRadius; - // console.log("hc", ); - // return hc <= shipRadius; } function detectCornerCollision([xc, yc], [x, y]) { @@ -520,9 +496,9 @@ // console.log("actual corner", actualCorner); // if (corner) console.log("corner collision", corner); - const edge = z.find(({ edge: e, node: ee }) => { - const str = `${e.xa},${e.ya} ${e.xb},${e.yb}`; - return detectEdgeCollision(position, str, e); + const edge = z.find(({ edge: pts, node: ee }) => { + const str = `${pts.xa},${pts.ya} ${pts.xb},${pts.yb}`; + return detectEdgeCollision(position, pts); } ); @@ -573,19 +549,95 @@ let { x, y } = s.position; let position = [positionX, positionY] = restart ? [0, 0] : wrapPos(changeX + x, changeY + y); + let [xc, yc] = position; s.collision = detectCollisions(position, allWallCorners, findAllEdges(allEdgePts, position), getCollisionEdges(edgeszz, position)); - if (s.collision && !isLandable(s.collision.edge)) { - console.log("a", "position", position, s.position); - s.velocity = { x: 0, y: 0 }; - } else if (s.collision) { - console.log("b", s.position, s.collision); + // if (s.collision) { + // find final position of ship - s.velocity = { x: 0, y: 0 }; - s.position.y = Math.trunc(s.collision.edge.ya - 5); - s.isLanded = true; - s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`; + // const baseSlope = slope(s.collision.edge); + // const { xa, ya, xb, yb } = s.collision.edge; + // const baseSlope = slope(s.collision.edge); + + // console.log("slope of base", baseSlope); + + // if (baseSlope === -Infinity) { + // (↤) Vertical, normal left + // console.log("foot", xa + shipRadius, yc); + // } else if (baseSlope === Infinity) { + // (↦) Vertical, normal right + + // console.log("foot", xa - shipRadius, yc); + // } else if (Object.is(baseSlope, 0)) { + // (↥) Horizontal, normal up + // const el = document.createElementNS(namespaceURIsvg, 'line'); + // el.setAttribute('x1', xc); + // el.setAttribute('y1', ya); + // el.setAttribute('x2', xc); + // el.setAttribute('y2', yc); + // this point should be the position of the ship to make it + // adjacent to the collision edge without overlapping it + // console.log(el.getPointAtLength(5)); + // const collPt = el.getPointAtLength(5); + // drawLine(xc, ya, collPt.x, collPt.y); + + // console.log("foot", xc, ya - shipRadius); + // } else if (Object.is(baseSlope, -0)) { + // (↧) Horizontal, normal down + + // console.log("foot", xc, ya + shipRadius); + // } else { + // const foot = perpIntxn(baseSlope, xa, ya, xc, yc); + // console.log("foot", foot); + // drawLine(foot.x, foot.y, xc, yc) + // const el = document.createElementNS(namespaceURIsvg, 'line'); + // el.setAttribute('x1', foot.x); + // el.setAttribute('y1', foot.y); + // el.setAttribute('x2', xc); + // el.setAttribute('y2', yc); + // this point should be the position of the ship to make it + // adjacent to the collision edge without overlapping it + // console.log(el.getPointAtLength(5)); + // const collPt = el.getPointAtLength(5); + // drawLine(foot.x, foot.y, collPt.x, collPt.y); + // } + // } + + // if (s.collision && !isLandable(s.collision.edge)) { + // console.log("a", "position", position, s.position); + // s.velocity = { x: 0, y: 0 }; + // } else if (s.collision) { + // console.log("b", s.position, s.collision); + // + // s.velocity = { x: 0, y: 0 }; + // s.position.y = Math.trunc(s.collision.edge.ya - 5); + // s.isLanded = true; + // s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`; // console.log("ship landed", s, "edge", s.collision.edge.ya); + if (s.collision) { + console.log("a"); + s.velocity = { x: 0, y: 0 }; + const baseSlope = slope(s.collision.edge); + const normalSlope = 1 / -baseSlope; + const radAngle = Math.atan(normalSlope); + const { xa, ya, xb, yb } = s.collision.edge; + const foot = perpIntxn(baseSlope, xa, ya, xc, yc); + const el = document.createElementNS(namespaceURIsvg, 'line'); + el.setAttribute('x1', foot.x); + el.setAttribute('y1', foot.y); + el.setAttribute('x2', xc); + el.setAttribute('y2', yc); + // the problem is that by this point the ship is already closer than + // its radius so the line is less than 5 units long + console.log("foot", foot, "line", el); + const [posX, posY] = [5 * Math.sin(radAngle), 5 * Math.cos(radAngle)]; + const collPt = el.getPointAtLength(5); + // let l = drawLine(foot.x, foot.y, foot.x - posX, foot.y - posY); + let l = drawLine(foot.x, foot.y, foot.x - posY, foot.y - posX); + console.log("line length", l.getTotalLength(), l); + s.position = { x: foot.x - posY, y: foot.y - posX }; + // s.position = { x: collPt.x, y: collPt.y }; + s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`; } else { console.log("c");