0
\$\begingroup\$

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;
}
\$\endgroup\$
1
\$\begingroup\$
 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.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.