Find the bounce vector

This commit is contained in:
2026-01-23 14:48:28 -08:00
parent 55f6328d3f
commit e1cfff39f0

View File

@@ -128,7 +128,8 @@
<!-- <polygon class="wall" points="-10,10 10,10 10,40 -10,40" /> -->
<!-- <polygon class="wall" points="-10,10 10,30 -10,40 -20,20" /> -->
<polygon class="wall" points="-20,-10 0,10 -20,20 -30,0" />
<!-- <polygon class="wall" points="-20,-10 0,10 -20,20 -30,0" /> -->
<polygon class="wall" points="-20,-10 20,10 -20,20 -30,0" />
<!-- <polygon class="wall" points="-20,-50 -10,-50 -10,-60 -20,-60" /> -->
<!-- <polygon class="wall" points="20,50 10,50 10,60 20,60" /> -->
@@ -556,10 +557,12 @@ const Move = (() => {
const edgeSlope = slope(contact.edge);
const rise = contact.edge.yb-contact.edge.ya;
const run = contact.edge.xb-contact.edge.xa;
console.log("rise", rise, "run", run);
const edgeAngleTheta = Math.atan(rise/run);
console.log("EDGEANGLETETASADFSDDFSF", edgeAngleTheta, "degrees", edgeAngleTheta * 180 / Math.PI);
const edgeVector = { x: run, y: rise };
const normalVector = { x: rise, y: -run };
drawLine(p.x, p.y, p.x + normalVector.x, p.y + normalVector.y);
drawLine(p.x, p.x, p.x + v.x, p.y + v.y, "blue");
console.log("edgeVector", edgeVector, "normalVector", normalVector);
const edgeVectorMagnitude = Math.sqrt(edgeVector.x**2+edgeVector.y**2);
const velocityVectorMagnitude = Math.sqrt(v.y**2+v.x**2);
@@ -568,35 +571,111 @@ const Move = (() => {
// const velocityVectorCrossNormalVector = v.x * normalVector.y - v.y * normalVector.x;
const velocityVectorCrossNormalVector = v.y * normalVector.x - v.x * normalVector.y;
console.log("dotProduct", dotProduct, "normalVectorDotProduct", normalVectorDotProduct);
// console.log("dotProduct", dotProduct, "normalVectorDotProduct", normalVectorDotProduct);
const edgeTheta = Math.acos(dotProduct / (edgeVectorMagnitude * velocityVectorMagnitude));
const normalTheta = Math.acos(normalVectorDotProduct / (edgeVectorMagnitude * velocityVectorMagnitude));
console.log("VELOCITY", v);
console.log("theta between edge vector and velocity vector", edgeTheta, "degrees", edgeTheta * 180 / Math.PI);
console.log("theta between normal vector and velocity vector", normalTheta, "degrees", normalTheta * 180 / Math.PI);
console.log("cross product normal and velocity", velocityVectorCrossNormalVector);
const newTheta = (Math.PI - normalTheta) * 2;
drawLine(p.x - v.x, p.y - v.y, p.x, p.y, "blue");
drawLine(contact.edge.xa, contact.edge.ya, contact.edge.xb, contact.edge.yb, "green");
// drawLine(p.x, p.x, p.x + v.x, p.y + v.y, "blue");
// console.log("theta between edge vector and velocity vector", edgeTheta, "degrees", edgeTheta * 180 / Math.PI);
// console.log("theta between normal vector and velocity vector", normalTheta, "degrees", normalTheta * 180 / Math.PI);
// console.log("cross product normal and velocity", velocityVectorCrossNormalVector);
// const newTheta = (Math.PI - normalTheta) * 2;
const newTheta = edgeTheta;
// const newY = -Math.cos(newTheta) * velocityVectorMagnitude;
// const newX = Math.sin(newTheta) * velocityVectorMagnitude;
// console.log("theta", newTheta, "degrees", newTheta * 180 / Math.PI);
console.log("theta between velocity vector and edge vector", newTheta, "degrees", newTheta * 180 / Math.PI);
let newY;
let newX;
if (velocityVectorCrossNormalVector < 0) {
newX = Math.cos(newTheta) * velocityVectorMagnitude;
newY = Math.sin(newTheta) * velocityVectorMagnitude;
} else {
newX = Math.sin(newTheta) * velocityVectorMagnitude;
newY = Math.cos(newTheta) * velocityVectorMagnitude;
// if (velocityVectorCrossNormalVector < 0) {
// if (velocityVectorCrossNormalVector > 0) {
//
// newX = Math.cos(newTheta) * velocityVectorMagnitude;
// newY = Math.sin(newTheta) * velocityVectorMagnitude;
// } else {
// newX = Math.sin(newTheta) * velocityVectorMagnitude;
// newY = Math.cos(newTheta) * velocityVectorMagnitude;
// }
// newX = Math.cos(newTheta) * v.x;
// newY = -Math.sin(newTheta) * v.y;
// newX = Math.cos(edgeAngleTheta) * velocityVectorMagnitude;
// newY = -Math.sin(edgeAngleTheta) * velocityVectorMagnitude;
function vector(x, y) {
const vector = { x: x, y: y };
vector.magnitude = Math.sqrt(x**2+y**2);
vector.dx = vector.x / vector.magnitude;
vector.dy = vector.y / vector.magnitude;
vector.rightNormal = { x: vector.y, y: -vector.x };
vector.rightNormal.dx = vector.rightNormal.x / vector.magnitude;
vector.rightNormal.dy = vector.rightNormal.y / vector.magnitude;
return vector;
}
const vec1 = vector(v.x, v.y);
const vec2 = vector(run, rise);
// From https://stackoverflow.com/a/14886099
// 1. Find the dot product of vec1 and vec2
// Note: dx and dy are vx and vy divided over the length of the vector (magnitude)
// var dpA:Number = vec1.vx * vec2.dx + vec1.vy * vec2.dy;
const dpA = vec1.x * vec2.dx + vec1.y * vec2.dy;
// 2. Project vec1 over vec2
// var prA_vx:Number = dpA * vec2.dx;
const prAvx = dpA * vec2.dx;
// var prA_vy:Number = dpA * vec2.dy;
const prAvy = dpA * vec2.dy;
// 3. Find the dot product of vec1 and vec2's normal
// (left or right normal depending on line's direction, let's say left)
// vec.leftNormal --> vx = vec.vy; vy = -vec.vx;
// vec.rightNormal --> vx = -vec.vy; vy = vec.vx;
// var dpB:Number = vec1.vx * vec2.leftNormal.dx + vec1.vy * vec2.leftNormal.dy;
const dpB = vec1.x * vec2.rightNormal.dx + vec1.y * vec2.rightNormal.dy;
// 4. Project vec1 over vec2's left normal
// var prB_vx:Number = dpB * vec2.leftNormal.dx;
const prBvx = dpB * vec2.rightNormal.dx;
// var prB_vy:Number = dpB * vec2.leftNormal.dy;
const prBvy = dpB * vec2.rightNormal.dy;
// 5. Add the first projection prA to the reverse of the second -prB
// var new_vx:Number = prA_vx - prB_vx;
// var new_vy:Number = prA_vy - prB_vy;
newX = prAvx - prBvx;
newY = prAvy - prBvy;
// newX = v.x;
// newY = -v.y;
// what vector x,y for a vector that is newTheta away from edge vector?
console.log("newX", newX, "newY", newY);
drawLine(p.x, p.y, p.x + normalVector.x , p.y + normalVector.y, "black");
drawLine(p.x, p.y, p.x + newX , p.y + newY, "blue");
Velocity[entity_id] = {
// x: v.x * Math.sin(thetaX) + v.y * Math.cos(thetaY),
// y: v.y * Math.sin(thetaY) + v.x * Math.cos(thetaX)
x: newX,
// y: v.y * Math.sin(thetaY) + v.x * Math.cos(thetaX)
y: -newY
y: newY
};
console.log("VELOCITY AFTER", Velocity[entity_id]);
@@ -697,9 +776,9 @@ function init() {
started = false;
const mult = 10;
s.position = { x: 0, y: 0 };
s.position = { x: 0, y: -10 };
// s.velocity = { x: 0, y: -10 };
s.velocity = { x: -10, y: 0 };
s.velocity = { x: 10, y: 20 };
s.angularVelocity = 0;
// s. velocity = { x: -5*mult, y: 7*mult };
@@ -996,6 +1075,13 @@ function drawLine(xa, ya, xb, yb, color = "black") {
el.setAttribute('x2', xb);
el.setAttribute('y2', yb);
el.setAttribute('stroke', color);
const arrow = document.createElementNS(namespaceURIsvg, 'circle');
arrow.setAttribute('cx', xb);
arrow.setAttribute('cy', yb);
arrow.setAttribute('r', 1);
arrow.setAttribute('fill', 'teal');
svg.appendChild(arrow);
svg.appendChild(el);
return el;
}

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 57 KiB