WIP: Velocity while in contact with edge

This commit is contained in:
2026-01-20 16:27:57 -08:00
parent c6ed409915
commit ac9684f4cf

View File

@@ -336,18 +336,35 @@ const Move = (() => {
// 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 denom = (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);
if (roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1) { if (denom) {
const xs = (x1 + s * (x2 - x1)); const s = ((x3-x1)*(y4-y3)-(x4-x3)*(y3-y1))/denom;
const ys = (y1 + s * (y2 - y1)); const t = -((x2-x1)*(y3-y1)-(x3-x1)*(y2-y1))/denom;
collision.position = { x: xs, y: ys }; // const roundedT = +t.toFixed(2);
// const roundedS = +s.toFixed(2);
const roundedT = t;
const roundedS = s;
return true; // console.log("checking edge for collision", edge);
// console.log("position edge segs", positionSeg, edgeSeg);
// 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 * (x2 - x1));
const ys = (y1 + s * (y2 - y1));
// console.log("xs, yx", xs, ys);
// console.log("xc, yc", xc, yc);
collision.position = { x: xs, y: ys };
// collision.position = { x: xc, y: yc };
// console.log("position calculate by detectEdgeCollision", xs, ys);
return true;
}
} }
// return roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1; // return roundedS >= 0 && roundedS <= 1 && roundedT >= 0 && roundedT <= 1;
return; return;
}; };
@@ -481,11 +498,70 @@ const Move = (() => {
} else if (contact.edge) { } else if (contact.edge) {
// if (isLandable(contact.edge) && s.gearDown) s.isLanded = true; // if (isLandable(contact.edge) && s.gearDown) s.isLanded = true;
// console.log("contact", contact); // console.log("contact", contact);
// posP = edgeContactPosition(p.x, p.y, px, py, contact.edge, s.radius);
// console.log("position calculated by edgeContactPosition", posP);
posP = contact.position; posP = contact.position;
// console.log("edge contact position current", posP);
// const velBeforeColl = { vx: Velocity[entity_id].x, vy: Velocity[entity_id].y };
// console.log("velocity before collision", velBeforeColl);
const { xa, ya, xb, yb } = contact.edge;
const positionSeg = { x1: px, y1: py, x2: p.x, y2: p.y };
const edgeSeg = { x1: xa, y1: ya, x2: xb, y2: yb };
console.log("CURRENT POSITION", px, py);
console.log("INTENDED POSITION", p.x, p.y);
console.log("CONTACT POSITION", contact.position);
// if (px === posP.x && py === posP.y) {
// const m1 = slope({ xa: px, ya: py, xb: p.x, yb: p.y });
if (contact.edge.ya === contact.edge.yb && contact.edge.xa < contact.edge.xb) {
console.log("ON A FLAT EDGE");
// Velocity[entity_id] = { x: velX, y: velY };
if (v.y <= 0) {
Velocity[entity_id] = { x: v.x, y: v.y };
Position[entity_id] = { x: p.x, y: p.y };
} else if (v.y > 0) {
Velocity[entity_id] = { x: v.x, y: 0 };
Position[entity_id] = { x: p.x, y: contact.position.y };
}
// Velocity[entity_id].x = v.x;
// Position[entity_id] = { x: p.x, y: p.y };
}
// const m1 = slope({ xa: vx, ya: vy, xb: v.x, yb: v.y });
// const m2 = slope(contact.edge);
// const m2 = 1/-slope(contact.edge); //normal??
// we need the angle between the velocity and normal vector, no?
// const theta = Math.atan((m1-m2) / (1+m2*m2));
// const velX = v.x * Math.sin(theta);
// const velY = v.y * Math.cos(theta);
// console.log("vvvvvvvvvvvvvvvvvvvv", v);
// console.log("theta", theta);
// console.log("theta", theta, "velX", velX.toFixed(15), "velY", velY.toFixed(15));
// i need the normal force to push back
// Velocity[entity_id] = { x: velX, y: velY };
// Position[entity_id] = { x: p.x, y: p.y };
// } else {
// Velocity[entity_id] = { x: 0, y: 0 };
// Position[entity_id] = { x: posP.x, y: posP.y };
// }
// console.log("POSITIONSEG", positionSeg);
// console.log("EDGESEG", edgeSeg);
} }
Velocity[entity_id] = { x: 0, y: 0 }; // we need to map velocity in segments
Position[entity_id] = { x: posP.x, y: posP.y }; // Velocity[entity_id] = { x: 0, y: 0 };
// Position[entity_id] = { x: posP.x, y: posP.y };
// s.node.style.transform = `translate(${Position[entity_id].x}px, ${Position[entity_id].y}px)`; // s.node.style.transform = `translate(${Position[entity_id].x}px, ${Position[entity_id].y}px)`;
// } else if (current && s.collision) { // } else if (current && s.collision) {
@@ -1065,6 +1141,8 @@ function edgeContactPosition(xc, yc, x, y, edge, radius) {
const theta = Math.atan(normalSegLength / baseSegLength); const theta = Math.atan(normalSegLength / baseSegLength);
const h = (radius)/ Math.sin(theta); const h = (radius)/ Math.sin(theta);
console.log("HHHHHHHHHHHHHHHHHHHHHHHHHHHHH", h);
const cl = document.createElementNS(namespaceURIsvg, 'line'); const cl = document.createElementNS(namespaceURIsvg, 'line');
cl.setAttribute('x1', basePosIntxn.x); cl.setAttribute('x1', basePosIntxn.x);
cl.setAttribute('y1', basePosIntxn.y); cl.setAttribute('y1', basePosIntxn.y);
@@ -1282,7 +1360,6 @@ function animate(timestamp) {
frameCount++; frameCount++;
} }
const newPos = updateShip(s, elapsed);
// s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`; // s.node.style.transform = `translate(${s.position.x}px, ${s.position.y}px)`;
@@ -1294,10 +1371,11 @@ function animate(timestamp) {
Move.update({ entity_id }, elapsed); Move.update({ entity_id }, elapsed);
}); });
// s.node.style.transform = `translate(${newPos.x}px, ${newPos.y}px)`; let newPos = updateShip(s, elapsed);
s.node.style.transform = `translate(${Position[Ships[0].entity_id].x}px, ${Position[Ships[0].entity_id].y}px)`; newPos = Position[Ships[0].entity_id];
positionEl.innerText = `${Position[Ships[0].entity_id].x.toFixed(1)},${Position[Ships[0].entity_id].y.toFixed(1)}`; s.node.style.transform = `translate(${newPos.x}px, ${newPos.y}px)`;
positionEl.innerText = `${newPos.x.toFixed(1)},${newPos.y.toFixed(1)}`;
// updateEdges(position); // updateEdges(position);
if (drawCollisionLines) updateTriangles(position); if (drawCollisionLines) updateTriangles(position);

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 50 KiB