0

enter image description here

I keep getting this error when using points[i+2], it doesn't return an error, but doesn't work as supposed to either when using points[i+1] (line 60). I can't seem to figure out why this error is happening. I looked in the console and don't know what undefined should be.

var canvas = document.getElementById('canvas');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
var ctx = canvas.getContext('2d');

var GLOBAL = {};

var point1 = [300, 300];
var point2 = [245, 55];
var point3 = [23, 143];
var point4 = [40, 200];

/*
 * y = mx + b
 * b = y - mx
 * m = y - b/x
 * x = y - b/m
 */
function lineSide(a, b, c) {
  var m = (b[1] - a[1]) / (b[0] - a[0]);
  var b = a[1] - (m * a[0]);

  var result = function(x, y) {
    if (y < m * x + b) return 0;
    else if (y > m * x + b) return 1;
    else if (y == m * x + b) return 2;
    //TODO implement error handling
  }(c[0], c[1]);

  switch (result) {
    case 0:
      return 'lt';
      break;
    case 1:
      return 'gt';
      break;
    case 2:
      return 'eq';
      break;
    default:
      return 'asdf';
      break;
  }
}

function inBounds(p, points) {
  var bcheck = [],
    pcheck = [];
  for (var i = 0; i < points.length; i++) {
    var pointa, pointb;
    if (i + 1 >= points.length) {
      pointa = points[i];
      pointb = points[0];
      bcheck.push(lineSide(pointa, pointb, points[1]));
    } else {
      pointa = points[i];
      pointb = points[i + 1];
      console.log(i + 2);
      console.log(points[i + 2]);
      bcheck.push(lineSide(pointa, pointb, points[i + 2])); // <-- THE PROBLEM AREA.
    }
  }
  // console.log(bcheck);

  for (var i = 0; i < points.length; i++) {
    var pointa, pointb;
    if (i + 1 >= points.length) {
      pointa = points[i];
      pointb = points[0];
      pcheck.push(lineSide(pointa, pointb, p));
    } else {
      pointa = points[i];
      pointb = points[i + 1];
      pcheck.push(lineSide(pointa, pointb, p));
    }
  }

  console.log(pcheck)
  for (var i in bcheck) {
    if (bcheck[i] != pcheck[i]) return false;
  }

  return true;
}

canvas.onmousemove = function(e) {
  GLOBAL.mouseX = e.clientX;
  GLOBAL.mouseY = e.clientY;
}

function render() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  if (inBounds([GLOBAL.mouseX, GLOBAL.mouseY], [point1, point2, point3, point4])) {
    ctx.fillStyle = 'red';
  } else {
    ctx.fillStyle = 'black';
  }

  ctx.beginPath();
  ctx.moveTo(point1[0], point1[1]);
  ctx.lineTo(point2[0], point2[1]);
  ctx.lineTo(point3[0], point3[1]);
  ctx.lineTo(point4[0], point4[1]);
  ctx.closePath();
  ctx.fill();

  window.requestAnimationFrame(render);
}

render();
marisusis
  • 342
  • 4
  • 20

1 Answers1

0

The loop inside inBounds() needs to be adjusted.

Either line 60 needs to only add by one:

bcheck.push(lineSide(pointa, pointb, points[i + 1])); // <-- THE PROBLEM AREA.

Or the if block on line 51 needs to add by two:

if (i + 2 >= points.length) {

I'm not entirely sure what you're trying to accomplish with the loop, so adjust as necessary.

jsFiddle of option #2.

The shape highlighting seems to break when the cursor exits through the bottom border. That's because the onmousemove event is only on the canvas element. You can change that event to be on the entire document, or add an onmouseleave event to the canvas element.

canvas.onmouseleave = function(e) {
    GLOBAL.mouseX = undefined;
    GLOBAL.mouseY = undefined;
};
fotijr
  • 946
  • 11
  • 20
  • `c` is defined by `points[i]` in the function `inBounds`, but on the last iteriation of the array `points`, `c` becomes undefined, i can't figure out why – marisusis Jun 29 '16 at 15:18
  • Sorry, I missed where you were defining `points`. It's an array of arrays, the issues was with your loop. – fotijr Jun 29 '16 at 15:43
  • I'm trying to detect collision between the mouse and the shape defined by `points[]` – marisusis Jun 29 '16 at 15:47
  • The jsFiddle does that except for when the mouse leaves the shape through the bottom border. – fotijr Jun 29 '16 at 16:08
  • That's the problem – marisusis Jun 29 '16 at 16:18
  • @spacegeek224 you asked why you were getting the exception. I'll update to include info on why the shape isn't turning black. – fotijr Jun 29 '16 at 16:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115987/discussion-between-fotijr-and-spacegeek224). – fotijr Jun 29 '16 at 16:43
  • I answered the original question, please consider marking the answer as accepted or updating your question. I also refactored you logic in this [fiddle](https://jsfiddle.net/2xhsz1zL/) by applying [this SO question](http://stackoverflow.com/questions/22521982/js-check-if-point-inside-a-polygon). – fotijr Jul 01 '16 at 11:11