WIP: adjusting edge collision distance

This commit is contained in:
2026-01-09 10:38:32 -08:00
parent c250275b1d
commit 50a851eb2f

View File

@@ -76,7 +76,7 @@
} }
line#velocity-indicator { line#velocity-indicator {
stroke: blue; stroke: none;
/* stroke-width: 1px; */ /* stroke-width: 1px; */
} }
@@ -292,6 +292,9 @@ const map = (function(els) {
let allStartingEdges; let allStartingEdges;
init(); init();
const b = map.edges.map(({ edge }) => getEdgeCollisionBoundary(edge, shipRadius));
b.forEach(b => drawLine(b.xa, b.ya, b.xb, b.yb, "orange"));
function distance(x1, y1, x2, y2) { function distance(x1, y1, x2, y2) {
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2); return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
} }
@@ -540,20 +543,32 @@ function isLandable(edge) {
// return Object.is(slope(edge), +0); // return Object.is(slope(edge), +0);
} }
function getEdgeCollisionBoundary(edge, dist) {
const { xa, ya, xb, yb } = edge;
const length = distance(xa, ya, xb, yb);
const rise = yb - ya;
const run = xb - xa;
const riol = rise / length * dist;
const ruol = run / length * dist;
return { xa: xa + riol, ya: ya - ruol, xb: xb + riol, yb: yb - ruol};
}
function detectEdgeCollision([xc, yc], [x, y], radius) { function detectEdgeCollision([xc, yc], [x, y], radius) {
return ({ edge, wall }) => { return ({ edge, wall }) => {
if (xc === x && yc === y) return; if (xc === x && yc === y) return;
const { xa, ya, xb, yb } = edge; // const { xa, ya, xb, yb } = edge;
const length = distance(xa, ya, xb, yb); // const length = distance(xa, ya, xb, yb);
const rise = yb - ya; // const rise = yb - ya;
const run = xb - xa; // const run = xb - xa;
//
const riol = rise / length * radius; // const riol = rise / length * radius;
const ruol = run / length * radius; // const ruol = run / length * radius;
//
// const edgeSeg = { xa: xa + riol, ya: ya - ruol, xb: xb + riol, yb: yb - ruol};
const edgeSeg = getEdgeCollisionBoundary(edge, radius);
const positionSeg = { xa: x, ya: y, xb: xc, yb: yc }; const positionSeg = { xa: x, ya: y, xb: xc, yb: yc };
const edgeSeg = { xa: xa + riol, ya: ya - ruol, xb: xb + riol, yb: yb - ruol};
const { xa: x1, ya: y1, xb: x2, yb: y2 } = positionSeg; const { xa: x1, ya: y1, xb: x2, yb: y2 } = positionSeg;
const { xa: x3, ya: y3, xb: x4, yb: y4 } = edgeSeg; const { xa: x3, ya: y3, xb: x4, yb: y4 } = edgeSeg;
@@ -676,14 +691,19 @@ function edgeContactPosition(xc, yc, x, y, edge, radius) {
const positionSeg = { x1: x, y1: y, x2: xc, y2: yc }; const positionSeg = { x1: x, y1: y, x2: xc, y2: yc };
const edgeSeg = { x1: xa, y1: ya, x2: xb, y2: yb }; const edgeSeg = { x1: xa, y1: ya, x2: xb, y2: yb };
drawLine(x, y, xc, yc, "green");
const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, x, y); const baseNrmlIntxn = perpIntxn(baseSlope, xa, ya, x, y);
const basePosIntxn = lineIntxnPt(edgeSeg, positionSeg); const basePosIntxn = lineIntxnPt(edgeSeg, positionSeg);
const baseSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, basePosIntxn.x, basePosIntxn.y); const baseSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, basePosIntxn.x, basePosIntxn.y);
const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, x, y); const normalSegLength = distance(baseNrmlIntxn.x, baseNrmlIntxn.y, x, y);
drawLine(baseNrmlIntxn.x, baseNrmlIntxn.y, basePosIntxn.x, basePosIntxn.y, "blue");
drawLine(baseNrmlIntxn.x, baseNrmlIntxn.y, x, y, "purple");
const theta = Math.atan(normalSegLength / baseSegLength); const theta = Math.atan(normalSegLength / baseSegLength);
const h = radius / Math.sin(theta); const h = (radius)/ Math.sin(theta);
const cl = document.createElementNS(namespaceURIsvg, 'line'); const cl = document.createElementNS(namespaceURIsvg, 'line');
cl.setAttribute('x1', basePosIntxn.x); cl.setAttribute('x1', basePosIntxn.x);
@@ -691,7 +711,11 @@ function edgeContactPosition(xc, yc, x, y, edge, radius) {
cl.setAttribute('x2', x); cl.setAttribute('x2', x);
cl.setAttribute('y2', y); cl.setAttribute('y2', y);
return cl.getPointAtLength(h); const pt = cl.getPointAtLength(h);
drawLine(basePosIntxn.x, basePosIntxn.y, pt.x, pt.y, "yellow");
// return cl.getPointAtLength(h);
return pt;
} }
function lineIntxnPt({ x1, y1, x2, y2 }, { x1: x3, y1: y3, x2: x4, y2: y4 }) { function lineIntxnPt({ x1, y1, x2, y2 }, { x1: x3, y1: y3, x2: x4, y2: y4 }) {
@@ -734,7 +758,9 @@ function updateShip(s, elapsed) {
const p = { x: pDelta.x + px, y: pDelta.y + py }; const p = { x: pDelta.x + px, y: pDelta.y + py };
current = s.collision; current = s.collision;
s.collision = detectCollision([px, py], p, s.velocity, shipRadius, map); const tempRadius = 10;
s.collision = detectCollision([px, py], p, s.velocity, tempRadius, map);
if (s.collision) console.log("COLLISION", s.collision); if (s.collision) console.log("COLLISION", s.collision);
legs.style.display = s.gearDown ? "initial" : "none"; legs.style.display = s.gearDown ? "initial" : "none";
@@ -750,7 +776,7 @@ function updateShip(s, elapsed) {
if (s.collision.corner) { if (s.collision.corner) {
posP = cornerContactPosition(p.x, p.y, px, py, s.collision.corner, shipRadius); posP = cornerContactPosition(p.x, p.y, px, py, s.collision.corner, shipRadius);
} else if (s.collision.edge) { } else if (s.collision.edge) {
posP = edgeContactPosition(p.x, p.y, px, py, s.collision.edge, shipRadius); posP = edgeContactPosition(p.x, p.y, px, py, s.collision.edge, tempRadius);
} }
s.velocity = { x: 0, y: 0 }; s.velocity = { x: 0, y: 0 };
@@ -838,12 +864,12 @@ function updateLines(elapsed, walls, position, velocity) {
function init() { function init() {
started = false; started = false;
const mult = 10000; const mult = 10;
s.position = { x: 10, y: 10 }; s.position = { x: 10, y: 10 };
s.velocity = { x: 0, y: 0 }; // s.velocity = { x: 0, y: 0 };
// s. velocity = { x: 2*mult, y: 7*mult }; s. velocity = { x: -5*mult, y: 7*mult };
s.acceleration = { x: 0, y: 0 }; s.acceleration = { x: 0, y: 0 };
s.rotate = 0; s.rotate = 0;

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 33 KiB