From d2a8758fb87eba3e2d2d621d12192ba1c983bfa0 Mon Sep 17 00:00:00 2001 From: Catalin Constantin Mititiuc Date: Fri, 30 Jan 2026 10:55:07 -0800 Subject: [PATCH] WIP: rounding position values --- html/images/space.svg | 178 +++++++++++++++++++++++++++++++++++------- 1 file changed, 148 insertions(+), 30 deletions(-) diff --git a/html/images/space.svg b/html/images/space.svg index 2168519..a376ae3 100644 --- a/html/images/space.svg +++ b/html/images/space.svg @@ -129,7 +129,7 @@ - + @@ -233,12 +233,46 @@ const Acceleration = {}; // systems const Move = (() => { const metersPerMillisecond = 0.001; + // const expo = 1e15; + const expo = 1e8; // Triangle has a clockwise orientation function isClockwise([xa, ya], [xb, yb], [xc, yc]) { // https://en.wikipedia.org/wiki/Curve_orientation#Practical_considerations // Determinant for a convex polygon const det = (xb - xa) * (yc - ya) - (xc - xa) * (yb - ya); + console.log("xa, ya, xb, yb, xc, yc", xa, ya, xb, yb, xc, yc); + const detEx = (xb*expo - xa*expo) * (yc*expo - ya*expo) - (xc*expo - xa*expo) * (yb*expo - ya*expo); + console.log("=----", xb*expo - xa*expo, yc*expo - ya*expo, xc*expo - xa*expo, yb*expo - ya*expo); + console.log("=----", xb*expo, xa*expo, yc*expo, ya*expo, xc*expo, xa*expo, yb*expo, ya*expo); + console.log("=----", xb*expo - xa*expo, yc*expo - ya*expo, xc*expo - xa*expo, yb*expo - ya*expo); + console.log("=----", (xb*expo - xa*expo) * (yc*expo - ya*expo), (xc*expo - xa*expo) * (yb*expo - ya*expo)); + console.log("detxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", detEx * 1e-16); + + // (8.0046e+33) / 1e30 + // -> 8004.599999999999 + // 8.0046e+33 * 1e-30 + // -> 8004.6 + // -0.574 * 1e-8 + // -57399999.99999999 + // -0.574 / 1e8 + // -> -5.74e-9 + // -0.574 * 1e9 + // -574000000 + // -0.574 / 1e-8 + // -57399999.99999999 + // -0.574 * 1e8 + // -57399999.99999999 + // -0.574 * 1e9 + // -574000000 + // -0.574 * 1e10 + // -5740000000 + // -0.574 * 1e11 + // -57399999999.99999 + + + // console.log(xb, xa, yc, ya, xc, xa, yb, ya); + console.log("dettttttttttttttttttttt", det); return det < 0; } @@ -341,35 +375,60 @@ const Move = (() => { const positionSeg = { xa: x, ya: y, xb: xc, yb: yc }; 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; + const { xa: x3, ya: y3, xb: x4, yb: y4 } = edge; // https://en.wikipedia.org/wiki/Intersection_(geometry)#Two_line_segments // https://en.wikipedia.org/wiki/Cramer%27s_rule#Explicit_formulas_for_small_systems - const denom = (x2-x1)*(y4-y3)-(x4-x3)*(y2-y1); + // const denom = (x2-x1)*(y4-y3)-(x4-x3)*(y2-y1); + + // console.log("x2", x2, "x1", x1, "y4", y4, "y3", y3, "x4", x4, "x3", x3, "y2", y2, "y1", y1); + + // console.log("denom", denom); + const x21 = +(x2-x1).toPrecision(13); + const y43 = +(y4-y3).toPrecision(13); + const x43 = +(x4-x3).toPrecision(13); + const y21 = +(y2-y1).toPrecision(13); + const denom = +(x21*y43-x43*y21).toPrecision(13); + const x31 = +(x3-x1).toPrecision(13); + const y31 = +(y3-y1).toPrecision(13); + + console.log("DENOM", denom); if (denom) { - const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/denom; - const t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/denom; + // const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/denom; + // const t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/denom; // const roundedT = +t.toFixed(2); // const roundedS = +s.toFixed(2); - const roundedT = +t.toFixed(15); - const roundedS = +s.toFixed(15); + // const roundedT = +t.toFixed(15); + // const roundedS = +s.toFixed(15); + const s = +(+(x31*y43-x43*y31).toPrecision(13) / denom).toPrecision(13); + const t = +(-(x21*y31-x31*y21).toPrecision(13) / denom).toPrecision(13); // console.log("checking edge for collision", edge); // console.log("position edge segs", positionSeg, edgeSeg); // console.log("s", s, "t", t); + // console.log("testing edge", edge); + // console.log("position seg", positionSeg); + // console.log("s", s, "roundedS", roundedS, "t", t, "roundedT", roundedT); + console.log("s", s, "t", t); // if (roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1) { - if (s >= 0 && s <= 1 && t >= 0 && t <= 1) { - const xs = (x1 + +s.toFixed(15) * (x2 - x1)); - const ys = (y1 + +s.toFixed(15) * (y2 - y1)); + if (s >= 0 && s < 1 && t >= 0 && t <= 1) { // this falls through + // if (s >= 0 && s <= 1 && t >= 0 && t <= 1) { // this sometimes falls through + const xs = +((x1 + s * +(x2 - x1).toPrecision(13))).toPrecision(13); + const ys = +((y1 + s * +(y2 - y1).toPrecision(13))).toPrecision(13); + console.log("xs", xs, "ys", ys); + + collision.position = { x: xs, y: ys }; + // console.log("xs, yx", xs, ys); // console.log("xc, yc", xc, yc); // collision.position = { x: xs, y: ys }; - collision.position = { x: +xs.toFixed(15), y: +ys.toFixed(15) }; + // collision.position = { x: +xs.toFixed(15), y: +ys.toFixed(15) }; - console.log("BLSAEKJSDFGLSKDJF"); + // console.log("BLSAEKJSDFGLSKDJF"); // collision.position = { x: xc, y: yc }; // console.log("position calculate by detectEdgeCollision", xs, ys); @@ -482,7 +541,7 @@ const Move = (() => { return [...edgeColl, ...cornerColl]; } - +// Math.round(3.141592653589793e+15 / 1) function vector(x, y) { const vector = { x: x, y: y }; vector.magnitude = Math.sqrt(x**2+y**2); @@ -542,16 +601,44 @@ const Move = (() => { const { x: vx, y: vy } = Velocity[entity_id]; const { x: ax, y: ay } = Acceleration[entity_id]; + // console.log("elapsed", elapsed); + // console.log("px", px, "py", py); + // console.log("vx", vx, "vy", vy); + // console.log("ax", ax, "ay", ay); + const v = { x: vx > 0 && vx + ax <= 0 ? 0 : vx + ax, y: vy > 0 && vy + ay <= 0 ? 0 : vy + ay }; + // v.x = +v.x.toPrecision(13); + // v.y = +v.y.toPrecision(13); + + // console.log("future v", v); + + const exp = 1e4 const p = { - x: px + elapsed * v.x * metersPerMillisecond, - y: py + elapsed * v.y * metersPerMillisecond + // x: px + elapsed * v.x * metersPerMillisecond, + // y: py + elapsed * v.y * metersPerMillisecond + x: Math.round((px + elapsed * v.x * metersPerMillisecond) * 100) / 100, + y: Math.round((py + elapsed * v.y * metersPerMillisecond) * 100) / 100, + + // x: (px * exp + elapsed * 1000 * v.x / 1000) / exp, + // y: (py * exp + elapsed * 1000 * v.y / 1000) / exp }; + console.log("----------elapsed", elapsed) + console.log("velocity", v); + console.log("current position", px, py); + console.log("future position", p); + // console.log("px + elapsed * 1000 * v.x / 1000", px + elapsed * 1000 * v.x / 1000 / 1000); + // 0.57 * 1000 * 20 / 1000 + + // p.x = +p.x.toPrecision(13); + // p.y = +p.y.toPrecision(13); + + // console.log("future p", p); + const contacts = detectContacts([px, py], p, v, s.radius, map, false); if (contacts.length !== 0) { @@ -562,6 +649,9 @@ const Move = (() => { if (contact.corner) { contact.position = cornerContactPosition(p.x, p.y, px, py, contact.corner, s.radius); + contact.position.x = +contact.position.x.toPrecision(13); + contact.position.y = +contact.position.y.toPrecision(13); + // console.log("contact position", contact.position); // drawLine(contact.position.x, contact.position.y, contact.position.x + vx, contact.position.y + vy, "blue"); @@ -585,8 +675,8 @@ const Move = (() => { } else if (contact.edge) { // if (isLandable(contact.edge) && s.gearDown) s.isLanded = true; const accVect = vector(ax, ay); - const rise = contact.edge.yb-contact.edge.ya; - const run = contact.edge.xb-contact.edge.xa; + const rise = (contact.edge.yb-contact.edge.ya).toPrecision(16); + const run = (contact.edge.xb-contact.edge.xa); const edgeNrmlVect = vector(rise, -run); const velocityVect = vector(v.x, v.y); @@ -606,7 +696,7 @@ const Move = (() => { const reverseP = { x: -pVect.x, y: -pVect.y }; const reverseA = { x: -aVect.x, y: -aVect.y }; - // add reverseP and v vectors together + // add reverseP and v vectors together and a vector const prVonNx = reverseP.x + v.x + reverseA.x; const prVonNy = reverseP.y + v.y + reverseA.y; // console.log("velocity vector", velocityVect); @@ -617,6 +707,9 @@ const Move = (() => { // drawLine(px, py, px + edgeNrmlVect.x, py + edgeNrmlVect.y, "black"); // drawLine(contact.position.x, contact.position.y, contact.position.x + prVonNx, contact.position.y + prVonNy, "teal"); + const side = isClockwise([contact.edge.xa, contact.edge.ya], [contact.edge.xb, contact.edge.yb], [px, py]); + console.log("Side of edge I'm on", side < 0 ? "side A" : "side B"); + // contact.velocity = { x: prVonNx, y: prVonNy }; Velocity[entity_id] = { x: prVonNx, y: prVonNy }; console.log("contact.position", contact.position); @@ -633,7 +726,11 @@ const Move = (() => { x: contact.position.x + elapsed * prVonNx * metersPerMillisecond, y: contact.position.y + elapsed * prVonNy * metersPerMillisecond }; + + newP.x = +newP.x.toPrecision(13); + newP.y = +newP.y.toPrecision(13); console.log("newP", newP); + drawCircle(newP.x, newP.y, "red", 0.1); Position[entity_id] = newP; } @@ -730,13 +827,13 @@ function init() { // s.velocity = { x: -10, y: 20 }; // s.velocity = { x: 10, y: 20 }; // s.velocity = { x: -20, y: 40 }; - s.velocity = { x: 0, y: 10 }; + s.velocity = { x: -1, y: 2 }; s.angularVelocity = 0; // s. velocity = { x: -5*mult, y: 7*mult }; // drawCircle(0, 0); - // s.acceleration = { x: 0, y: 10 }; + // s.acceleration = { x: 1, y: 3 }; s.acceleration = { x: 0, y: 0 }; Ships.forEach(({ entity_id }) => { @@ -1083,18 +1180,31 @@ function detectEdgeCollision([xc, yc], [x, y], radius, gearDown) { 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 } = edge; // 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); + // const denom = +((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1)).toPrecision(13); + const x21 = +(x2-x1).toPrecision(13); + const y43 = +(y4-y3).toPrecision(13); + const x43 = +(x4-x3).toPrecision(13); + const y21 = +(y2-y1).toPrecision(13); + const denom = +(x21*y43-x43*y21).toPrecision(13); + const x31 = +(x3-x1).toPrecision(13); + const y31 = +(y3-y1).toPrecision(13); - if (roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1) { - const xs = (x1 + s * (x2 - x1)); - const ys = (y1 + s * (y2 - y1)); - collision.position = { x: xs, y: ys }; + const s = +(+(x31*y43-x43*y31).toPrecision(13) / denom).toPrecision(13); + const t = +(-(x21*y31-x31*y21).toPrecision(13) / denom).toPrecision(13); + + // const s = +(((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/denom).toPrecision(13); + // const t = +(-((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/denom).toPrecision(13); + + + if (s >= 0 && s <= 1 && t >= 0 && t <= 1) { + + const xs = (x1 + s * +(x2 - x1).toPrecision(13)); + const ys = (y1 + s * +(y2 - y1).toPrecision(13)); + collision.position = { x: +xs.toPrecision(13), y: +ys.toPrecision(13) }; return true; } @@ -1412,8 +1522,14 @@ function firstFrame(timestamp) { } function animate(timestamp) { - const elapsed = timestamp - previous; - const delta = timestamp - zero; + console.log("----------animate timestamp", timestamp, "previous", previous); + + // 2064.26 * 1000 - 2036.26 * 1000 + // 28000.000000000233 + + // const elapsed = (timestamp * 1000 - previous * 1000) / 1000; + const elapsed = (Math.round(timestamp * 1000) - Math.round(previous * 1000)) / 1000; + const delta = (timestamp * 1000 - zero * 1000) / 1000; previous = timestamp; if (delta >= 1000) { @@ -1447,6 +1563,8 @@ function animate(timestamp) { newVel = Velocity[Ships[0].entity_id]; s.node.style.transform = `translate(${newPos.x}px, ${newPos.y}px)`; + // s.node.style.transform = `translate(${Math.round(newPos.x)}px, ${Math.round(newPos.y)}px)`; + // console.log("translation", s.node.style.transform); positionEl.innerText = `${newPos.x.toFixed(1)},${newPos.y.toFixed(1)}`; velocityEl.innerText = `${newVel.x.toFixed(1)},${newVel.y.toFixed(1)}`;