Refactor edge collision detect function
This commit is contained in:
@@ -656,18 +656,36 @@
|
|||||||
return Object.is(slope(edge), +0);
|
return Object.is(slope(edge), +0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectEdgeCollision([xc, yc], { xa, ya, xb, yb }, shipRadius) {
|
function detectEdgeCollision([xc, yc], [x, y], radius) {
|
||||||
const da = distance(xa, ya, xc, yc);
|
return ({ edge, wall }) => {
|
||||||
const db = distance(xb, yb, xc, yc);
|
if (xc === x && yc === y) return;
|
||||||
// TODO: calculate this one ahead of time
|
|
||||||
const dc = distance(xa, ya, xb, yb);
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Altitude_(triangle)#Altitude_in_terms_of_the_sides
|
const { xa, ya, xb, yb } = edge;
|
||||||
// Find altitude of side c (the base)
|
const rise = yb - ya;
|
||||||
const s = (1 / 2) * (da + db + dc);
|
const run = xb - xa;
|
||||||
const hc = (2 / dc) * Math.sqrt(s * (s - da) * (s - db) * (s - dc));
|
const length = distance(xa, ya, xb, yb);
|
||||||
|
|
||||||
return +hc.toFixed(2) <= shipRadius;
|
const riol = rise / length * radius;
|
||||||
|
const ruol = run / length * radius;
|
||||||
|
|
||||||
|
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: x3, ya: y3, xb: x4, yb: y4 } = edgeSeg;
|
||||||
|
|
||||||
|
// https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
|
||||||
|
// 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 t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
|
||||||
|
const roundedT = +t.toFixed(2);
|
||||||
|
const roundedS = +s.toFixed(2);
|
||||||
|
|
||||||
|
// console.log("edgeSeg", edgeSeg);
|
||||||
|
// console.log("s", roundedS, "t", roundedT);
|
||||||
|
|
||||||
|
return roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectCornerCollision([xc, yc], [x, y], radius) {
|
function detectCornerCollision([xc, yc], [x, y], radius) {
|
||||||
@@ -915,61 +933,34 @@
|
|||||||
});
|
});
|
||||||
// console.log("edges facing ship", efs);
|
// console.log("edges facing ship", efs);
|
||||||
|
|
||||||
const positionSeg = { xa: x, ya: y, xb: xc, yb: yc };
|
// const positionSeg = { xa: x, ya: y, xb: xc, yb: yc };
|
||||||
|
|
||||||
console.log("positionSeg", positionSeg);
|
// console.log("positionSeg", positionSeg);
|
||||||
|
|
||||||
const edgeCollision = efs.find(({ edge, wall }) => {
|
const edgeColl = efs.find(detectEdgeCollision([xc, yc], [x, y], shipRadius));
|
||||||
const { xa, ya, xb, yb } = edge;
|
|
||||||
if (xc === x && yc === y) return;
|
|
||||||
|
|
||||||
const rise = yb - ya;
|
// efs.forEach(({ edge, wall }) => {
|
||||||
const run = xb - xa;
|
// const { xa, ya, xb, yb } = edge;
|
||||||
const length = distance(xa, ya, xb, yb);
|
// const sl = slope(edge);
|
||||||
|
// if (sl === Infinity) {
|
||||||
const riol = rise / length * shipRadius;
|
// drawLine(xa + shipRadius, ya, xb + shipRadius, yb);
|
||||||
const ruol = run / length * shipRadius;
|
// } else if (sl === -Infinity) {
|
||||||
|
// drawLine(xa - shipRadius, ya, xb - shipRadius, yb);
|
||||||
const edgeSeg = { xa: xa + riol, ya: ya - ruol, xb: xb + riol, yb: yb - ruol};
|
// } else if (Object.is(sl, -0)) {
|
||||||
|
// drawLine(xa, ya + shipRadius, xb, yb + shipRadius);
|
||||||
const { xa: x1, ya: y1, xb: x2, yb: y2 } = positionSeg;
|
// } else if (sl === 0) {
|
||||||
const { xa: x3, ya: y3, xb: x4, yb: y4 } = edgeSeg;
|
// drawLine(xa, ya - shipRadius, xb, yb - shipRadius);
|
||||||
|
// } else {
|
||||||
// https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments
|
// const rise = yb - ya;
|
||||||
// https://en.wikipedia.org/wiki/Cramer%27s_rule#Explicit_formulas_for_small_systems
|
// const run = xb - xa;
|
||||||
const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
|
// const length = distance(xa, ya, xb, yb)
|
||||||
const t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1));
|
//
|
||||||
const roundedT = +t.toFixed(2);
|
// const riol = rise / length * shipRadius;
|
||||||
const roundedS = +s.toFixed(2);
|
// const ruol = run / length * shipRadius;
|
||||||
|
//
|
||||||
console.log("edgeSeg", edgeSeg);
|
// drawLine(xa + riol, ya - ruol, xb + riol, yb - ruol);
|
||||||
console.log("s", roundedS, "t", roundedT);
|
// }
|
||||||
|
// });
|
||||||
return roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
efs.forEach(({ edge, wall }) => {
|
|
||||||
const { xa, ya, xb, yb } = edge;
|
|
||||||
const sl = slope(edge);
|
|
||||||
if (sl === Infinity) {
|
|
||||||
drawLine(xa + shipRadius, ya, xb + shipRadius, yb);
|
|
||||||
} else if (sl === -Infinity) {
|
|
||||||
drawLine(xa - shipRadius, ya, xb - shipRadius, yb);
|
|
||||||
} else if (Object.is(sl, -0)) {
|
|
||||||
drawLine(xa, ya + shipRadius, xb, yb + shipRadius);
|
|
||||||
} else if (sl === 0) {
|
|
||||||
drawLine(xa, ya - shipRadius, xb, yb - shipRadius);
|
|
||||||
} else {
|
|
||||||
const rise = yb - ya;
|
|
||||||
const run = xb - xa;
|
|
||||||
const length = distance(xa, ya, xb, yb)
|
|
||||||
|
|
||||||
const riol = rise / length * shipRadius;
|
|
||||||
const ruol = run / length * shipRadius;
|
|
||||||
|
|
||||||
drawLine(xa + riol, ya - ruol, xb + riol, yb - ruol);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// corners ahead of ship
|
// corners ahead of ship
|
||||||
const fCollC = getForwardCollisionCorners(ws, { x, y }, s.velocity);
|
const fCollC = getForwardCollisionCorners(ws, { x, y }, s.velocity);
|
||||||
@@ -983,24 +974,7 @@
|
|||||||
|
|
||||||
const cornerColl = cwcd.find(detectCornerCollision([xc, yc], [x, y], shipRadius));
|
const cornerColl = cwcd.find(detectCornerCollision([xc, yc], [x, y], shipRadius));
|
||||||
|
|
||||||
// const edgeColl = collE.find(({ edge, wall }) => {
|
s.collision = edgeColl || cornerColl;
|
||||||
// const { xa, ya, xb, yb } = edge;
|
|
||||||
// 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);
|
|
||||||
//
|
|
||||||
// // 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));
|
|
||||||
// console.log("hc", hc);
|
|
||||||
//
|
|
||||||
// return +hc.toFixed(2) <= shipRadius;
|
|
||||||
// });
|
|
||||||
|
|
||||||
// s.collision = cornerColl || edgeCollision;
|
|
||||||
s.collision = edgeCollision || cornerColl;
|
|
||||||
|
|
||||||
if (s.collision) console.log("COLLISION", s.collision);
|
if (s.collision) console.log("COLLISION", s.collision);
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 43 KiB |
Reference in New Issue
Block a user