diff --git a/html/images/space.svg b/html/images/space.svg
index ecb4e78..fca9026 100644
--- a/html/images/space.svg
+++ b/html/images/space.svg
@@ -189,16 +189,18 @@
let acceleration; // meters per second per second
let rotate = 0;
- let mult = 20;
+ let mult = 1000;
const s = {
position: { x: 0, y: 0 },
+ velocity: { x: 5, y: -10 },
+ // velocity: { x: 5*mult, y: -10*mult },
// velocity: { x: 0, y: -10 },
// velocity: { x: 10, y: 10 },
// velocity: { x: -10, y: -10 },
// velocity: { x: 10, y: -10 },
// velocity: { x: -10, y: 10 },
- velocity: { x: -10, y: 0 },
+ // velocity: { x: -10, y: 0 },
// velocity: { x: 10, y: 0 },
// velocity: { x: 0, y: -5000 },
@@ -266,6 +268,13 @@
};
});
+ const mcs = ws.reduce(
+ (acc, wall) => [...acc, ...wall.corners.map(c => ({ corner: c, node: wall }))],
+ []
+ );
+
+ console.log("corners on map", mcs);
+
const edgeszz = [...walls].map(wall => {
const es = wall.getAttribute('points').split(' ').map((coords, i, arr) => {
const [x, y] = coords.split(',');
@@ -406,15 +415,10 @@
function getForwardCollisionCorners(walls, position, velocity) {
const { x: x1, y: y1 } = position;
const { x: x2, y: y2 } = velocity;
- // const a = { x: -100, y: 0 };
- // const b = { x: 100, y: 0 };
-
- // console.log("VELOCITY", velocity);
const { x: vx, y: vy } = velocity;
- // console.log("velocity", velocity, "position", position);
- let perppts;
+ let perppts = {};
if (vx === 0 && vy === 0) {
// none
@@ -460,15 +464,15 @@
}
const { a, b } = perppts;
- drawLine(a.x, a.y, b.x, b.y);
+ if (a && b) drawLine(a.x, a.y, b.x, b.y);
return walls.reduce((acc, w) => {
- const filtered = w.corners.filter(c => {
+ const filtered = a && b ? w.corners.filter(c => {
// https://stackoverflow.com/a/1560510
const det = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
return det > 0;
- });
+ }).map(c => ({ corner: c, node: w.node })) : [];
return [...acc, ...filtered];
}, []);
@@ -661,6 +665,62 @@
return actualCorner;
}
+ function withinCollisionDistance({ x: x1, y: y1 }, { x: x2, y: y2 }) {
+ const diffx = x2;
+ const diffy = y2;
+ const detv = x2 * y1 - y2 * x1;
+ const dv = Math.sqrt(diffy ** 2 + diffx ** 2);
+ const slopev = slope({ xa: x1, ya: y1, xb: x1 + x2, yb: y1 + y2 });
+
+ return ({ corner: { x: x0, y: y0 }, node: n }) => {
+ const velNormIntxn = perpIntxn(slopev, x1, y1, x0, y0);
+ // console.log("x0", x0, "y0", y0, "velNormIntxn", velNormIntxn);
+ const dx = Math.max(x0, velNormIntxn.x) - Math.min(x0, velNormIntxn.x);
+ const dy = Math.max(y0, velNormIntxn.y) - Math.min(y0, velNormIntxn.y);
+ const d = Math.sqrt(dy ** 2 + dx ** 2);
+ // console.log("dddddddddddd", d);
+ return d <= shipRadius;
+ // return true;
+ };
+ }
+
+ function lineSegIntxn(point, seg1, seg2) {
+ const { x: x0, y: y0 } = point;
+ const { xa: x1, ya: y1, xb: x2, yb: y2 } = seg1;
+ const { xa: x3, ya: y3, xb: x4, yb: y4 } = seg2;
+ // console.log(`s = (${x3-x1} + t${x4-x3}) / ${x2-x1}`);
+ // console.log(`s = (${x3-x1} + t${x4-x3}) / ${x2-x1}`);
+ // console.log(`${y2-y1} * (${x3-x1} + t${x4-x3}) / ${x2-x1} - t${y4-y3} = ${y3-y1}`);
+ // console.log(`${y2-y1} * (${x3-x1} + t${x4-x3}) / ${x2-x1} - t${y4-y3} = ${y3-y1}`);
+ //
+ // console.log(`${x2-x1}s - t${x4-x3} = ${x3-x1}`);
+ // console.log(`${y2-y1}s - t${y4-y3} = ${y3-y1}`);
+
+ // https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
+ const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
+ const t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
+
+ // const x = x1 + s * (x2-x1);
+ // const y = y3 + t * (y4-y3);
+
+ const xs = x1+s*(x2-x1);
+ const ys = y1+s*(y2-y1);
+ const xt = x3+t*(x4-x3);
+ const yt = y3+t*(y4-y3);
+
+ // console.log("point", point, "seg1", seg1, "seg2", seg2);
+ // console.log("s", s, "t", t);
+ // console.log("xs", xs, "ys", ys, "xt", xt, "yt", yt);
+
+ if (s >= 0 && t <= 1) {
+ console.log("CORNER COLLISION", "point", point, "position segment", seg1);
+ }
+
+ // console.log(`x1 ${x1} y1 ${y1} x2 ${x2} y2 ${y2} x3 ${x3} y3 ${y3} x4 ${x4} y4 ${y4} x0 ${x0} y0 ${y0}`);
+
+ // console.log("point", point, "seg1", seg1, "seg2", seg2, "s", s, "t", t);
+ }
+
function cornerCollisionPosition({ x: x1, y: y1 }, { x: x2, y: y2 }) {
// todo1: i only want the collisions ahead, not behind
// todo2: how do we tell if we've passed the collision point already?
@@ -674,7 +734,9 @@
return ({ corner: { x: x0, y: y0 }, node: n }) => {
const velNormIntxn = perpIntxn(slopev, x1, y1, x0, y0);
const d = Math.abs(diffy * x0 - diffx * y0 + detv) / dv;
- const b = Math.sqrt(shipRadius ** 2 - d ** 2);
+ // console.log("dddddddddddd", d);
+ // const b = Math.sqrt(shipRadius ** 2 - d ** 2);
+ const b = Math.sqrt(Math.max(shipRadius, d) ** 2 - Math.min(shipRadius, d) ** 2);
const cl = document.createElementNS(namespaceURIsvg, 'line');
cl.setAttribute('x1', velNormIntxn.x);
@@ -756,36 +818,83 @@
const changeY = 0.001 * elapsed * velocityY;
let { x, y } = s.position;
- // console.log("current position", x, y);
+ console.log("current position", x, y);
// console.log("elapsed", elapsed, "changeX", changeX, "changeY", changeY);
// let position = [positionX, positionY] = restart ? [0, 0] : wrapPos(changeX + x, changeY + y);
let position = [positionX, positionY] = [changeX + x, changeY + y];
let [xc, yc] = position;
- // console.log("future position", xc, yc);
+ console.log("future position", xc, yc);
const collE = getCollisionEdges(edgeszz, position);
// console.log("position", { x, y }, "velocity", s.velocity);
- const collC = getCollisionCorners(ws, { x, y }, s.velocity);
+ // const collC = getCollisionCorners(ws, { x, y }, s.velocity);
const fCollC = getForwardCollisionCorners(ws, { x, y }, s.velocity);
+ // console.log("corners ahead of ship", fCollC);
+
+ cwcd = fCollC.filter(withinCollisionDistance({ x, y }, s.velocity));
+
+ // console.log("corners on collision path", cwcd);
+
+ // cwcd.forEach(c => {
+ // const positionSeg = { xa: x, ya: y, xb: xc, yb: yc };
+ // const positionSeg = { xa: xc, ya: yc, xb: x, yb: y };
+ // const slopeps = slope(positionSeg);
+ // const posNormIntxn = perpIntxn(slopeps, x, y, c.corner.x, c.corner.y);
+ // const cornerSeg = { xa: c.corner.x, ya: c.corner.y, xb: posNormIntxn.x, yb: posNormIntxn.y };
+ //
+ // lineSegIntxn(c.corner, positionSeg, cornerSeg);
+ // });
// console.log("collision corners", collC);
- console.log("forward collision corners", fCollC);
- ccps = collC.map(cornerCollisionPosition({ x, y }, s.velocity));
+ ccps = fCollC.filter(cornerCollisionPosition({ x, y }, s.velocity));
// console.log("corner collision position", ccps);
current = s.collision;
- s.collision = detectCollisions(position, allWallCorners, collE);
+ // s.collision = detectCollisions(position, allWallCorners, collE);
+ s.collision = cwcd.find(c => {
+ const d = distance(c.corner.x, c.corner.y, xc, yc);
+
+ const positionSeg = { xa: xc, ya: yc, xb: x, yb: y };
+ const slopeps = slope(positionSeg);
+ const posNormIntxn = perpIntxn(slopeps, x, y, c.corner.x, c.corner.y);
+ const cornerSeg = { xa: c.corner.x, ya: c.corner.y, xb: posNormIntxn.x, yb: posNormIntxn.y };
+
+ const { x: x0, y: y0 } = c.corner;
+ const { xa: x1, ya: y1, xb: x2, yb: y2 } = positionSeg;
+ const { xa: x3, ya: y3, xb: x4, yb: y4 } = cornerSeg;
+
+ const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
+ const t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
+
+ return d <= shipRadius || (s >= 0 && t <= 1);
+ });
// legs.style.display = !legs.style.display || legs.style.display === "none" ? "initial" : "none";
legs.style.display = s.gearDown ? "initial" : "none";
if (!current && s.collision) {
- const baseSlope = slope(s.collision.edge);
- if (Object.is(baseSlope, 0) && s.gearDown) s.isLanded = true;
- const clPos = collisionPosition(s.collision.edge, s.position, s.velocity, s.gearDown && Object.is(baseSlope, 0) ? shipRadius + 1 : shipRadius);
+ // const baseSlope = slope(s.collision.edge);
+ // if (Object.is(baseSlope, 0) && s.gearDown) s.isLanded = true;
+ // const clPos = collisionPosition(s.collision.edge, s.position, s.velocity, s.gearDown && Object.is(baseSlope, 0) ? shipRadius + 1 : shipRadius);
+ const diffx = xc - x;
+ const diffy = yc - y;
+ const detv = xc * y - yc * x;
+ const dv = Math.sqrt(diffy ** 2 + diffx ** 2);
+ const slopep = slope({ xa: x, ya: y, xb: xc, yb: yc });
+ const posNormIntxn = perpIntxn(slopep, x, y, s.collision.corner.x, s.collision.corner.y);
+ const d = Math.abs(diffy * s.collision.corner.x - diffx * s.collision.corner.y + detv) / dv;
+ const b = Math.sqrt(Math.max(shipRadius, d) ** 2 - Math.min(shipRadius, d) ** 2);
+
+ const cl = document.createElementNS(namespaceURIsvg, 'line');
+ cl.setAttribute('x1', posNormIntxn.x);
+ cl.setAttribute('y1', posNormIntxn.y);
+ cl.setAttribute('x2', x);
+ cl.setAttribute('y2', y);
+
+ const posP = cl.getPointAtLength(b);
s.velocity = { x: 0, y: 0 };
- s.position = { x: clPos.x, y: clPos.y }
+ s.position = { x: posP.x, y: posP.y }
s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
} else if (current && s.collision) {
s.velocity = { x: 0, y: 0 };