Clean up
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
<!-- <svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg"> -->
|
||||||
<!-- <svg viewBox="-10 -10 60 60" version="1.1" xmlns="http://www.w3.org/2000/svg"> -->
|
<svg viewBox="-10 -10 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
<style>
|
<style>
|
||||||
foreignObject {
|
foreignObject {
|
||||||
font-size: 4pt;
|
font-size: 4pt;
|
||||||
@@ -186,6 +186,24 @@
|
|||||||
</foreignObject>
|
</foreignObject>
|
||||||
|
|
||||||
<script type="text/javascript">//<![CDATA[
|
<script type="text/javascript">//<![CDATA[
|
||||||
|
// entities
|
||||||
|
// const Ships = [{ entity_id: "ship_1" }];
|
||||||
|
// const Walls = [{ entity_id: "wall_1" }, { entity_id: "wall_2" }];
|
||||||
|
|
||||||
|
// systems
|
||||||
|
// Move.update = ({ entity_id }) => {
|
||||||
|
// reads Velocity[entity_id]
|
||||||
|
// sets Position[entity_id]
|
||||||
|
// };
|
||||||
|
|
||||||
|
// components
|
||||||
|
// Velocity = { "ship_1": { x: 0, y: 0 }};
|
||||||
|
// Position = { "ship_1": { x: 0, y: 0 }};
|
||||||
|
// Points = {
|
||||||
|
// "wall_1": "0,0 2,0 1,1",
|
||||||
|
// "wall_2": "0,0 -1,1 -2,0",
|
||||||
|
// };
|
||||||
|
|
||||||
const namespaceURIsvg = 'http://www.w3.org/2000/svg';
|
const namespaceURIsvg = 'http://www.w3.org/2000/svg';
|
||||||
const degsRegex = /(-?\d*\.{0,1}\d+)deg/g;
|
const degsRegex = /(-?\d*\.{0,1}\d+)deg/g;
|
||||||
const regex = /(-?\d*\.{0,1}\d+)px/g;
|
const regex = /(-?\d*\.{0,1}\d+)px/g;
|
||||||
@@ -208,11 +226,11 @@
|
|||||||
|
|
||||||
const s = {
|
const s = {
|
||||||
position: { x: 0, y: 0 },
|
position: { x: 0, y: 0 },
|
||||||
velocity: { x: 0, y: 0 },
|
// velocity: { x: 0, y: 0 },
|
||||||
// velocity: { x: -100, y: -100 },
|
// velocity: { x: -100, y: -100 },
|
||||||
|
|
||||||
// velocity: { x: 5, y: 7 },
|
// velocity: { x: 2, y: 7 },
|
||||||
// velocity: { x: 5*mult, y: 8*mult },
|
velocity: { x: 2*mult, y: 7*mult },
|
||||||
// acceleration: { x: 5, y: 7 },
|
// acceleration: { x: 5, y: 7 },
|
||||||
acceleration: { x: 0, y: 0 },
|
acceleration: { x: 0, y: 0 },
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
@@ -271,25 +289,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const edges = corners.map(({ x: xa, y: ya }, i, arr) => {
|
const edges = corners.map(({ x: xa, y: ya }, i, arr) => {
|
||||||
// return [+x, +y];
|
|
||||||
// const [xb, yb] = arr[i]++;
|
|
||||||
const { x: xb, y: yb } = arr[(i + 1) % arr.length];
|
const { x: xb, y: yb } = arr[(i + 1) % arr.length];
|
||||||
// console.log("coords", { xa: +x, ya: +y, xb: +xb, yb: +yb, inverse: wall.classList.contains("inverse") });
|
return { xa: xa, ya: ya, xb: xb, yb: yb };
|
||||||
|
|
||||||
// return `${+x},${+y} ${+xb},${+yb}`;
|
|
||||||
return {
|
|
||||||
xa: xa,
|
|
||||||
ya: ya,
|
|
||||||
xb: xb,
|
|
||||||
yb: yb,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return { node, corners, edges };
|
||||||
node,
|
|
||||||
corners,
|
|
||||||
edges
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const mcs = ws.reduce(
|
const mcs = ws.reduce(
|
||||||
@@ -389,40 +393,15 @@
|
|||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCollisionEdges(walls, [xc, yc]) {
|
function getForwardEdges(edges, { x, y }) {
|
||||||
return walls.reduce((acc, wall) => {
|
return edges.filter(({ edge }) => {
|
||||||
return [...acc, ...wall.edges.filter(({ xa, ya, xb, yb }) => {
|
const { xa, ya, xb, yb } = edge;
|
||||||
return [isClockwise, isAcute].every(c => c([xa, ya], [xb, yb], [xc, yc]));
|
const det = (xb - xa) * (y - ya) - (x - xa) * (yb - ya);
|
||||||
}).map(edge => ({ edge, wall }))];
|
return det < 0;
|
||||||
}, []);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// function getCollisionCorners(ws, { x: px, y: py }, { x: vx, y: vy }) {
|
function getForwardCorners(walls, position, velocity) {
|
||||||
function getCollisionCorners(ws, { 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 ws.reduce((acc, w) => {
|
|
||||||
const filtered = w.corners.filter(c => {
|
|
||||||
const { x: x0, y: y0 } = c;
|
|
||||||
const velNormIntxn = perpIntxn(slopev, x1, y1, x0, y0);
|
|
||||||
// const d = distance(velNormIntxn.x, velNormIntxn.y , x0, y0);
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Line_defined_by_two_points
|
|
||||||
const d = Math.abs(diffy * x0 - diffx * y0 + detv) / dv;
|
|
||||||
// console.log("corner", c, "d", d, "shipRadius", shipRadius);
|
|
||||||
return d <= shipRadius;
|
|
||||||
}).map(c => ({ corner: c, node: w.node }));
|
|
||||||
// });
|
|
||||||
|
|
||||||
return [...acc, ...filtered];
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getForwardCollisionCorners(walls, position, velocity) {
|
|
||||||
const { x: x1, y: y1 } = position;
|
const { x: x1, y: y1 } = position;
|
||||||
const { x: x2, y: y2 } = velocity;
|
const { x: x2, y: y2 } = velocity;
|
||||||
|
|
||||||
@@ -611,6 +590,16 @@
|
|||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function drawCircle(cx, cy, color = "black", r = 1) {
|
||||||
|
const el = document.createElementNS(namespaceURIsvg, 'circle');
|
||||||
|
el.setAttribute('cx', cx);
|
||||||
|
el.setAttribute('cy', cy);
|
||||||
|
el.setAttribute('r', r);
|
||||||
|
el.setAttribute('fill', color);
|
||||||
|
svg.appendChild(el);
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
function slope({ xa, ya, xb, yb }) {
|
function slope({ xa, ya, xb, yb }) {
|
||||||
return (yb - ya) / (xb - xa);
|
return (yb - ya) / (xb - xa);
|
||||||
}
|
}
|
||||||
@@ -645,6 +634,16 @@
|
|||||||
const roundedT = +t.toFixed(2);
|
const roundedT = +t.toFixed(2);
|
||||||
const roundedS = +s.toFixed(2);
|
const roundedS = +s.toFixed(2);
|
||||||
|
|
||||||
|
if (roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1) {
|
||||||
|
const xs = (x1 + s * (x2 - x1));
|
||||||
|
const ys = (y1 + s * (y2 - y1));
|
||||||
|
const xt = (x3 + t * (x4 - x3));
|
||||||
|
const yt = (y3 + t * (y4 - y3));
|
||||||
|
const collisionPt = [xs, ys];
|
||||||
|
// [xs, ys] === [xt, yt];
|
||||||
|
drawCircle(...collisionPt, "red"); // collision position
|
||||||
|
}
|
||||||
|
|
||||||
return roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1;
|
return roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -666,12 +665,28 @@
|
|||||||
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 } = cornerSeg;
|
const { xa: x3, ya: y3, xb: x4, yb: y4 } = cornerSeg;
|
||||||
|
|
||||||
|
drawLine(x1, y1, x2, y2);
|
||||||
|
drawLine(x3, y3, x4, y4);
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
|
// https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
|
||||||
// https://en.wikipedia.org/wiki/Cramer%27s_rule#Explicit_formulas_for_small_systems
|
// https://en.wikipedia.org/wiki/Cramer%27s_rule#Explicit_formulas_for_small_systems
|
||||||
const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
|
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 t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
|
||||||
const roundedT = +t.toFixed(2);
|
const roundedT = +t.toFixed(2);
|
||||||
|
|
||||||
|
if (s >= 0 && roundedT <= 1) {
|
||||||
|
const xs = (x1 + s * (x2 - x1));
|
||||||
|
const ys = (y1 + s * (y2 - y1));
|
||||||
|
const xt = (x3 + roundedT * (x4 - x3));
|
||||||
|
const yt = (y3 + roundedT * (y4 - y3));
|
||||||
|
// [xs, ys] and [xt, yt] should be equal ([xs, ys] === [xy, yt])
|
||||||
|
// (...or about equal, notwithstanding rounding errors)
|
||||||
|
const sCollisionPt = [xs, ys];
|
||||||
|
const tCollisionPt = [xt, yt];
|
||||||
|
drawCircle(...sCollisionPt, "red");
|
||||||
|
drawCircle(...tCollisionPt, "blue");
|
||||||
|
}
|
||||||
|
|
||||||
return s >= 0 && roundedT <= 1;
|
return s >= 0 && roundedT <= 1;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -776,22 +791,16 @@
|
|||||||
let [xc, yc] = position;
|
let [xc, yc] = position;
|
||||||
// console.log("future position", xc, yc);
|
// console.log("future position", xc, yc);
|
||||||
|
|
||||||
const efs = mes.filter(({ edge, wall }) => {
|
const efs = getForwardEdges(mes, { x, y })
|
||||||
const { xa, ya, xb, yb } = edge;
|
|
||||||
const det = (xb - xa) * (y - ya) - (x - xa) * (yb - ya);
|
|
||||||
return det < 0;
|
|
||||||
});
|
|
||||||
// console.log("edges facing ship", efs);
|
// console.log("edges facing ship", efs);
|
||||||
|
|
||||||
const edgeColl = efs.find(detectEdgeCollision([xc, yc], [x, y], shipRadius));
|
const edgeColl = efs.find(detectEdgeCollision([xc, yc], [x, y], shipRadius));
|
||||||
|
|
||||||
// corners ahead of ship
|
// corners ahead of ship
|
||||||
const fCollC = getForwardCollisionCorners(ws, { x, y }, s.velocity);
|
const fCollC = getForwardCorners(ws, { x, y }, s.velocity);
|
||||||
// console.log("corners ahead of ship", fCollC);
|
|
||||||
|
|
||||||
// corners within collision distance
|
// corners within collision distance (are on the collision path)
|
||||||
cwcd = fCollC.filter(withinCollisionDistance({ x, y }, s.velocity));
|
cwcd = fCollC.filter(withinCollisionDistance({ x, y }, s.velocity));
|
||||||
// console.log("corners on collision path", cwcd);
|
|
||||||
const cornerColl = cwcd.find(detectCornerCollision([xc, yc], [x, y], shipRadius));
|
const cornerColl = cwcd.find(detectCornerCollision([xc, yc], [x, y], shipRadius));
|
||||||
|
|
||||||
current = s.collision;
|
current = s.collision;
|
||||||
@@ -806,7 +815,7 @@
|
|||||||
|
|
||||||
// const baseSlope = slope(s.collision.edge);
|
// const baseSlope = slope(s.collision.edge);
|
||||||
// if (Object.is(baseSlope, 0) && s.gearDown) s.isLanded = true;
|
// if (Object.is(baseSlope, 0) && s.gearDown) s.isLanded = true;
|
||||||
|
s.isLanded = true;
|
||||||
let posP;
|
let posP;
|
||||||
if (s.collision.corner) {
|
if (s.collision.corner) {
|
||||||
posP = cornerContactPosition(xc, yc, x, y, s.collision.corner, shipRadius);
|
posP = cornerContactPosition(xc, yc, x, y, s.collision.corner, shipRadius);
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
Reference in New Issue
Block a user