diff --git a/html/images/space.svg b/html/images/space.svg index 26416b0..59b6dd4 100644 --- a/html/images/space.svg +++ b/html/images/space.svg @@ -656,18 +656,36 @@ return Object.is(slope(edge), +0); } - function detectEdgeCollision([xc, yc], { xa, ya, xb, yb }, shipRadius) { - 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); + function detectEdgeCollision([xc, yc], [x, y], radius) { + return ({ edge, wall }) => { + if (xc === x && yc === y) return; - // 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)); + const { xa, ya, xb, yb } = edge; + const rise = yb - ya; + const run = xb - xa; + 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) { @@ -915,61 +933,34 @@ }); // 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 { xa, ya, xb, yb } = edge; - if (xc === x && yc === y) return; + const edgeColl = efs.find(detectEdgeCollision([xc, yc], [x, y], shipRadius)); - 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; - - 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; - }); - - 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); - } - }); + // 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 const fCollC = getForwardCollisionCorners(ws, { x, y }, s.velocity); @@ -983,24 +974,7 @@ const cornerColl = cwcd.find(detectCornerCollision([xc, yc], [x, y], shipRadius)); - // const edgeColl = collE.find(({ edge, wall }) => { - // 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; + s.collision = edgeColl || cornerColl; if (s.collision) console.log("COLLISION", s.collision);