Saturday, March 11, 2017

collision detection - Line rect intersection - lines behave like rays


Why is this? I have a simple ship that is a 14x14 rectangle, and a contour map. I want to be able to determine when the ship hits the ground. Here's a link to the JSFiddle.


Here's what happens now: the crosshairs indicate where the ship "exploded". The red lines indicate the ground line that was last processed. It seems that the ship explodes when it hits the ray that the line is part of.


Lunar Lander bug


Here's the code...


function collision() {
for(var i = 1; i < map.length; i++) {

var res;
var start = new VectorPoint((i - 1) * 20, map[i-1]);
var end = new VectorPoint(i * 20, map[i]);
c.strokeStyle = "#ff0000";
c.beginPath();
c.moveTo(start.x, start.y);
c.lineTo(end.x, end.y);
c.stroke();
c.strokeStyle = "#00ff00";
var d = VectorFunctions.sub(end, start);

var len = VectorFunctions.len(d);
d = VectorFunctions.norm(d);
res = rectLineCollision(start, d);
if(res != null && res > 0 && res < len) {
var insec = VectorFunctions.add(start, VectorFunctions.mul(d, res));
c.beginPath();
c.moveTo(insec.x - 10, insec.y);
c.lineTo(insec.x + 10, insec.y);
c.moveTo(insec.x, insec.y - 10);
c.lineTo(insec.x, insec.y + 10);

c.stroke();
console.log("Res: " + res + ", len: " + len);
break;
}
}
return res != null;
}

function rectLineCollision(start, d) {
var largestMin = -Number.MAX_VALUE;

var smallestMax = Number.MAX_VALUE;
for(var i = 0; i < 2; i++) {
var n = VectorFunctions.sub(shipCopy.body[i], shipCopy.body[i + 1]);
n = VectorFunctions.norm(n);
// the shipCopy.body is just an array of points
var sub1 = VectorFunctions.sub(shipCopy.body[i], start);
var sub2 = VectorFunctions.sub(shipCopy.body[i+1], start);
var e0 = VectorFunctions.dot(n, sub1);
var e1 = VectorFunctions.dot(n, sub2);
var f = VectorFunctions.dot(n, d);

if(Math.abs(f) > EPSILON) {
var t0 = e0 / f;
var t1 = e1 / f;
if(t0 > t1) {
var swap = t0;
t0 = t1;
t1 = swap;
}
largestMin = Math.max(largestMin, t0);
smallestMax = Math.min(smallestMax, t1);

if(largestMin > smallestMax) {
return null;
}
if(smallestMax < 0) {
return null;
}
}
else if(e0 * e1 > 0) {
return null;
}

}
return largestMin > 0 ? largestMin : smallestMax;
}

Answer



 276   // v: VectorPoint
277 // n: number
278 div: function(v, n) {
279 return new VectorPoint(v.x * n, v.y * n);
280 },


Looks like you copied and pasted the mul method but forgot to actually change the operators to a divide.


Making those changes will fix your application.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...