WIP: bounce off corners
This commit is contained in:
@@ -122,5 +122,4 @@ Delete your `.sitegen_cache` file.
|
|||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
- Bounce off corners algo
|
|
||||||
- Bounce off multiple simultaneous contacts
|
- Bounce off multiple simultaneous contacts
|
||||||
|
|||||||
@@ -127,11 +127,12 @@
|
|||||||
<!-- <polygon class="wall" points="20,-50 10,-50 10,-60 20,-60" /> -->
|
<!-- <polygon class="wall" points="20,-50 10,-50 10,-60 20,-60" /> -->
|
||||||
<!-- <polygon class="wall" points="-10,10 10,10 10,40 -10,40" /> -->
|
<!-- <polygon class="wall" points="-10,10 10,10 10,40 -10,40" /> -->
|
||||||
<!-- <polygon class="wall" points="-10,-40 10,-40 10,-20 -10,-20" /> -->
|
<!-- <polygon class="wall" points="-10,-40 10,-40 10,-20 -10,-20" /> -->
|
||||||
|
|
||||||
<polygon class="wall" points="-10,-40 10,-40 10,-15 -10,-15" />
|
<polygon class="wall" points="-10,-40 10,-40 10,-15 -10,-15" />
|
||||||
|
<polygon class="wall" points="-20,-10 20,10 -20,20 -30,0" />
|
||||||
|
|
||||||
<!-- <polygon class="wall" points="-10,10 10,30 -10,40 -20,20" /> -->
|
<!-- <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" /> -->
|
||||||
<!-- <polygon class="wall" points="20,50 10,50 10,60 20,60" /> -->
|
<!-- <polygon class="wall" points="20,50 10,50 10,60 20,60" /> -->
|
||||||
@@ -476,6 +477,59 @@ const Move = (() => {
|
|||||||
return [...edgeColl, ...cornerColl];
|
return [...edgeColl, ...cornerColl];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bounceVector(v, run, rise) {
|
||||||
|
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;
|
||||||
|
return {
|
||||||
|
x: prAvx - prBvx,
|
||||||
|
y: prAvy - prBvy,
|
||||||
|
vec1,
|
||||||
|
vec2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
update: ({ entity_id }, elapsed) => {
|
update: ({ entity_id }, elapsed) => {
|
||||||
const { x: px, y: py } = Position[entity_id];
|
const { x: px, y: py } = Position[entity_id];
|
||||||
@@ -496,88 +550,46 @@ const Move = (() => {
|
|||||||
|
|
||||||
if (contacts.length !== 0) {
|
if (contacts.length !== 0) {
|
||||||
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
console.log("CONTACTS", contacts);
|
||||||
let posP;
|
let posP;
|
||||||
const contact = contacts[0];
|
const contact = contacts[0];
|
||||||
|
|
||||||
if (contact.corner) {
|
if (contact.corner) {
|
||||||
Velocity[entity_id] = { x: 0, y: 0 };
|
contact.position = cornerContactPosition(p.x, p.y, px, py, contact.corner, s.radius);
|
||||||
|
console.log("contact position", contact.position);
|
||||||
|
drawLine(contact.position.x, contact.position.y, contact.position.x + vx, contact.position.y + vy, "blue");
|
||||||
|
|
||||||
|
const contactV = { x: contact.position.y - contact.corner.y, y: contact.position.x - contact.corner.x };
|
||||||
|
console.log("contactV", contactV);
|
||||||
|
const normalVect = { x: contact.position.x - contact.corner.x, y: contact.position.y - contact.corner.y };
|
||||||
|
console.log("normal vector", normalVect);
|
||||||
|
drawLine(contact.corner.x, contact.corner.y, contact.corner.x + normalVect.x, contact.corner.y + normalVect.y, "black");
|
||||||
|
|
||||||
|
const tangentVect = { x: normalVect.y, y: -normalVect.x };
|
||||||
|
drawLine(contact.position.x, contact.position.y, contact.position.x + tangentVect.x, contact.position.y + tangentVect.y, "green");
|
||||||
|
contact.velocity = bounceVector(v, tangentVect.x, tangentVect.y);
|
||||||
|
|
||||||
|
console.log("tangent vector", tangentVect);
|
||||||
|
|
||||||
|
drawLine(contact.position.x, contact.position.y, contact.position.x + contact.velocity.x, contact.position.y + contact.velocity.y, "blue");
|
||||||
|
|
||||||
|
// Velocity[entity_id] = { x: 0, y: 0 };
|
||||||
|
Velocity[entity_id] = contact.velocity;
|
||||||
Position[entity_id] = cornerContactPosition(p.x, p.y, px, py, contact.corner, s.radius);
|
Position[entity_id] = cornerContactPosition(p.x, p.y, px, py, contact.corner, s.radius);
|
||||||
} 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;
|
||||||
const isHorizontal = contact.edge.ya === contact.edge.yb;
|
// console.log("CURRENT POSITION", px, py);
|
||||||
const isVertical = contact.edge.xa === contact.edge.xb;
|
// console.log("INTENDED POSITION", p.x, p.y);
|
||||||
|
// console.log("CONTACT POSITION", contact.position);
|
||||||
console.log("CURRENT POSITION", px, py);
|
|
||||||
console.log("INTENDED POSITION", p.x, p.y);
|
|
||||||
console.log("CONTACT POSITION", contact.position);
|
|
||||||
|
|
||||||
const rise = contact.edge.yb-contact.edge.ya;
|
const rise = contact.edge.yb-contact.edge.ya;
|
||||||
const run = contact.edge.xb-contact.edge.xa;
|
const run = contact.edge.xb-contact.edge.xa;
|
||||||
|
|
||||||
drawLine(p.x - v.x, p.y - v.y, p.x, p.y, "blue"); // velocity vector
|
drawLine(p.x - v.x, p.y - v.y, p.x, p.y, "blue"); // velocity vector
|
||||||
console.log("velocity vector", v.x, v.y);
|
|
||||||
const det = v.x * rise - v.y * run;
|
const det = v.x * rise - v.y * run;
|
||||||
console.log("DEEEEEEEETTTTTTTTTTTTTTT", det);
|
|
||||||
|
|
||||||
drawLine(contact.edge.xa, contact.edge.ya, contact.edge.xb, contact.edge.yb, "green"); // edge vector
|
drawLine(contact.edge.xa, contact.edge.ya, contact.edge.xb, contact.edge.yb, "green"); // edge vector
|
||||||
|
|
||||||
let newY;
|
|
||||||
let newX;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function bounceVector(v, run, rise) {
|
|
||||||
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;
|
|
||||||
return {
|
|
||||||
x: prAvx - prBvx,
|
|
||||||
y: prAvy - prBvy,
|
|
||||||
vec1,
|
|
||||||
vec2
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// contact.velocity = { x: prAvx - prBvx, y: prAvy - prBvy };
|
// contact.velocity = { x: prAvx - prBvx, y: prAvy - prBvy };
|
||||||
contact.velocity = bounceVector(v, run, rise);
|
contact.velocity = bounceVector(v, run, rise);
|
||||||
|
|
||||||
@@ -685,7 +697,7 @@ function init() {
|
|||||||
s.position = { x: 0, y: -10 };
|
s.position = { x: 0, y: -10 };
|
||||||
// s.velocity = { x: 0, y: -10 };
|
// s.velocity = { x: 0, y: -10 };
|
||||||
// s.velocity = { x: 10, y: 20 };
|
// s.velocity = { x: 10, y: 20 };
|
||||||
s.velocity = { x: 0, y: 0 };
|
s.velocity = { x: 5, y: 0 };
|
||||||
s.angularVelocity = 0;
|
s.angularVelocity = 0;
|
||||||
|
|
||||||
// s. velocity = { x: -5*mult, y: 7*mult };
|
// s. velocity = { x: -5*mult, y: 7*mult };
|
||||||
@@ -986,7 +998,7 @@ function drawLine(xa, ya, xb, yb, color = "black") {
|
|||||||
arrow.setAttribute('cx', xb);
|
arrow.setAttribute('cx', xb);
|
||||||
arrow.setAttribute('cy', yb);
|
arrow.setAttribute('cy', yb);
|
||||||
arrow.setAttribute('r', 1);
|
arrow.setAttribute('r', 1);
|
||||||
arrow.setAttribute('fill', 'teal');
|
arrow.setAttribute('fill', color);
|
||||||
|
|
||||||
svg.appendChild(arrow);
|
svg.appendChild(arrow);
|
||||||
svg.appendChild(el);
|
svg.appendChild(el);
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
Reference in New Issue
Block a user