maskedLine

Version:

1.0

Added on:

11 Dec 2017 03:33

Tags:

Description:
JJ2+ has the maskedHLine and maskedVLine functions (and their derivatives) but those are only useful if you're checking a straight line. This function takes two arbitrary points (x0, y0) and (x1, y1) as arguments and checks if any pixel on a straight line between them is masked.

Note that the line is one pixel thick, so there is no guarantee that a rabbit will fit through whatever gap you're testing.
/*
 * Check whether any pixel on a line between two positions is masked
 *
 * Returns true if masked pixel is found, false if not.
 */
bool maskedLine(int x0, int y0, int x1, int y1, int layer = 4) {
  int x2;
  int y2;
  
  //straight lines
  if(x0 == x1 || y0 == y1) {
    if(y0 == y1) {
      if(x0 > x1) {
        x2 = x1; x1 = x0; x0 = x2; //swap
      }
      for(int x = x0; x < x1; x += 1) {
        if(jjLayers[layer].maskedPixel(x, y0)) {
          return true;
        }
      }
      return false;
    }

    if (y0 > y1) {
      y2 = y1; y1 = y0; y0 = y2; //swap
    }
    
    for(int y = y0; y < y1; y += 1) {
      if(jjLayers[layer].maskedPixel(x0, y)) {
        return true;
      }
    }
    return true;
  }
  
  
  //sloped lines
  bool steep = (abs(y1 - y0) > abs(x1 - x0));

  if (steep) {
    x2 = x0; x0 = y0; y0 = x2; //swap
    y2 = x1; x1 = y1; y1 = y2; //swap
  }

  if (x0 > x1) {
    x2 = x1; x1 = x0; x0 = x2; //swap
    y2 = y1; y1 = y0; y0 = y2; //swap
  }

  float dx = x1 - x0;
  float dy = abs(y1 - y0);

  float error = dx / 2.0f;
  int ystep = (y0 < y1) ? 1 : -1;

  int y = int(y0);
  int max_x = int(x1);

  for(int x = int(x0); x < max_x; x += 1) {
    if (steep) {
      if(jjLayers[layer].maskedPixel(y, x)) {
        return true;
      }
    } else {
      if(jjLayers[layer].maskedPixel(x, y)) {
        return true;
      }
    }

    error -= dy;
    if (error < 0) {
      y += ystep;
      error += dx;
    }
  }

  return false;
}