1

I'm using the p5.js library.

I'm making a program that is meant to automatically fill closed spaces but I'm having a problem. Sometimes the program fills half closed loops and I can't figure out why. If anyone could help me identify the problem I will fix it myself.

Here is an example of that problem:

You have to zoom in a lot or it breaks (on a side note if you know how to scale up the pixels that would also be great)

let pixelVals;
let checkedPixels;
let filledPixels;
let iter = 0;
let drawFilled;

function setup() {
  pixelVals = array(height, width, 4);

  createCanvas(25, 25);
  pixelDensity(1);

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      pixelVals[i][j][0] = 0;
      pixelVals[i][j][1] = 0;
      pixelVals[i][j][2] = 0;
      pixelVals[i][j][3] = 255;
    }
  }
}

function draw() {
  loadPixels();

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      pixelVals[i][j][1] = 0;
    }
  }

  if(mouseIsPressed) {
    if(mouseX < width && mouseX >= 0 && mouseY < height && mouseY >= 0) {
      pixelVals[mouseX][mouseY][0] = 255;
    }
  }

  checkEnclosed();

  updatePixels();
}

function checkEnclosed() {
  checkedPixels = array(height, width);
  filledPixels = array(height, width);

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      checkedPixels[i][j] = false;
      filledPixels[i][j] = false;
    }
  }

  for(var i = 0; i < height; i++) {
    for(var j = 0; j < width; j++) {
      if(!checkedPixels[i][j] && pixelVals[i][j][0] != 255) {
        drawFilled = true;
        checkSurroundings(i, j);
        if(drawFilled) {
          setFilled();
        } else {
          setFilledFalse();
        }
      }
    }
  }

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      for(var k = 0; k < 4; k++) {
        pixels[(i + j * width) * 4 + k] = pixelVals[i][j][k];
      }
    }
  }
}

function checkSurroundings(x, y) {
  pixelVals[x][y][1] = 255;
  filledPixels[x][y] = true;
  checkedPixels[x][y] = true;

  if(x == width - 1 || x == 0 || y == height - 1 || y == 0) {
    drawFilled = false;
  } else {
    if(x + 1 < width) {
      if(pixelVals[x + 1][y][0] != 255) {
        if(!checkedPixels[x + 1][y]) {
          checkSurroundings(x + 1, y)
        }
      }
    }
    if(x - 1 >= 0) {
      if(pixelVals[x - 1][y][0] != 255) {
        if(!checkedPixels[x - 1][y]) {
          checkSurroundings(x - 1, y)
        }
      }
    }
    if(y + 1 < height) {
      if(pixelVals[x][y + 1][0] != 255) {
        if(!checkedPixels[x][y + 1]) {
          checkSurroundings(x, y + 1)
        }
      }
    }
    if(y - 1 >= 0) {
      if(pixelVals[x][y - 1][0] != 255) {
        if(!checkedPixels[x][y - 1]) {
          checkSurroundings(x, y - 1)
        }
      }
    }
  }
}

function setFilled() {
  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      if(filledPixels[i][j]) {
        pixelVals[i][j][2] = 255;
      }
    }
  }
}

function setFilledFalse() {
  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      filledPixels[i][j] = false;
    }
  }
}

function array(length) {
  var arr = new Array(length || 0), i = length;

  if (arguments.length > 1) {
    var args = Array.prototype.slice.call(arguments, 1);
    while(i--) arr[length-1 - i] = array.apply(this, args);
  }
  return arr
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js"></script>

I'm new to JavaScript so ignore the messy code :).

let pixelVals;
let checkedPixels;
let filledPixels;
let iter = 0;
let drawFilled;

function setup() {
  pixelVals = array(height, width, 4);

  createCanvas(25, 25);
  pixelDensity(1);

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      pixelVals[i][j][0] = 0;
      pixelVals[i][j][1] = 0;
      pixelVals[i][j][2] = 0;
      pixelVals[i][j][3] = 255;
    }
  }
}

function draw() {
  loadPixels();

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      pixelVals[i][j][1] = 0;
    }
  }

  if(mouseIsPressed) {
    if(mouseX < width && mouseX >= 0 && mouseY < height && mouseY >= 0) {
      pixelVals[mouseX][mouseY][0] = 255;
    }
  }

  checkEnclosed();

  updatePixels();
}

function checkEnclosed() {
  checkedPixels = array(height, width);
  filledPixels = array(height, width);

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      checkedPixels[i][j] = false;
      filledPixels[i][j] = false;
    }
  }

  for(var i = 0; i < height; i++) {
    for(var j = 0; j < width; j++) {
      if(!checkedPixels[i][j] && pixelVals[i][j][0] != 255) {
        drawFilled = true;
        checkSurroundings(i, j);
        if(drawFilled) {
          setFilled();
        } else {
          setFilledFalse();
        }
      }
    }
  }

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      for(var k = 0; k < 4; k++) {
        pixels[(i + j * width) * 4 + k] = pixelVals[i][j][k];
      }
    }
  }
}

function checkSurroundings(x, y) {
  pixelVals[x][y][1] = 255;
  filledPixels[x][y] = true;
  checkedPixels[x][y] = true;

  if(x == width - 1 || x == 0 || y == height - 1 || y == 0) {
    drawFilled = false;
  } else {
    if(x + 1 < width) {
      if(pixelVals[x + 1][y][0] != 255) {
        if(!checkedPixels[x + 1][y]) {
          checkSurroundings(x + 1, y)
        }
      }
    }
    if(x - 1 >= 0) {
      if(pixelVals[x - 1][y][0] != 255) {
        if(!checkedPixels[x - 1][y]) {
          checkSurroundings(x - 1, y)
        }
      }
    }
    if(y + 1 < height) {
      if(pixelVals[x][y + 1][0] != 255) {
        if(!checkedPixels[x][y + 1]) {
          checkSurroundings(x, y + 1)
        }
      }
    }
    if(y - 1 >= 0) {
      if(pixelVals[x][y - 1][0] != 255) {
        if(!checkedPixels[x][y - 1]) {
          checkSurroundings(x, y - 1)
        }
      }
    }
  }
}

function setFilled() {
  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      if(filledPixels[i][j]) {
        pixelVals[i][j][2] = 255;
      }
    }
  }
}

function setFilledFalse() {
  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      filledPixels[i][j] = false;
    }
  }
}

function array(length) {
  var arr = new Array(length || 0), i = length;

  if (arguments.length > 1) {
    var args = Array.prototype.slice.call(arguments, 1);
    while(i--) arr[length-1 - i] = array.apply(this, args);
  }
  return arr
}

Much appreciated,

Zac

Rabbid76
  • 202,892
  • 27
  • 131
  • 174

1 Answers1

1

This was my solution by changing the checkSurroundings function:

function checkSurroundings(x, y) {
  pixelVals[x][y][1] = 255;
  filledPixels[x][y] = true;
  checkedPixels[x][y] = true;

  if(x == width - 1 || x == 0 || y == height - 1 || y == 0) {
    drawFilled = false;
  }
  if(x + 1 < width) {
    if(pixelVals[x + 1][y][0] != 255) {
      if(!checkedPixels[x + 1][y]) {
        checkSurroundings(x + 1, y)
      }
    }
  }
  if(x - 1 >= 0) {
    if(pixelVals[x - 1][y][0] != 255) {
      if(!checkedPixels[x - 1][y]) {
        checkSurroundings(x - 1, y)
      }
    }
  }
  if(y + 1 < height) {
    if(pixelVals[x][y + 1][0] != 255) {
      if(!checkedPixels[x][y + 1]) {
        checkSurroundings(x, y + 1)
      }
    }
  }
  if(y - 1 >= 0) {
    if(pixelVals[x][y - 1][0] != 255) {
      if(!checkedPixels[x][y - 1]) {
        checkSurroundings(x, y - 1)
      }
    }
  }
}

let pixelVals;
let checkedPixels;
let filledPixels;
let iter = 0;
let drawFilled;

function setup() {
  pixelVals = array(height, width, 4);

  createCanvas(25, 25);
  pixelDensity(1);

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      pixelVals[i][j][0] = 0;
      pixelVals[i][j][1] = 0;
      pixelVals[i][j][2] = 0;
      pixelVals[i][j][3] = 255;
    }
  }
}

function draw() {
  loadPixels();

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      pixelVals[i][j][1] = 0;
    }
  }

  if(mouseIsPressed) {
    if(mouseX < width && mouseX >= 0 && mouseY < height && mouseY >= 0) {
      pixelVals[mouseX][mouseY][0] = 255;
    }
  }

  checkEnclosed();

  updatePixels();
}

function checkEnclosed() {
  checkedPixels = array(height, width);
  filledPixels = array(height, width);

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      checkedPixels[i][j] = false;
      filledPixels[i][j] = false;
    }
  }

  for(var i = 0; i < height; i++) {
    for(var j = 0; j < width; j++) {
      if(!checkedPixels[i][j] && pixelVals[i][j][0] != 255) {
        drawFilled = true;
        checkSurroundings(i, j);
        if(drawFilled) {
          setFilled();
        } else {
          setFilledFalse();
        }
      }
    }
  }

  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      for(var k = 0; k < 4; k++) {
        pixels[(i + j * width) * 4 + k] = pixelVals[i][j][k];
      }
    }
  }
}

function checkSurroundings(x, y) {
  pixelVals[x][y][1] = 255;
  filledPixels[x][y] = true;
  checkedPixels[x][y] = true;

  if(x == width - 1 || x == 0 || y == height - 1 || y == 0) {
    drawFilled = false;
  }
  if(x + 1 < width) {
    if(pixelVals[x + 1][y][0] != 255) {
      if(!checkedPixels[x + 1][y]) {
        checkSurroundings(x + 1, y)
      }
    }
  }
  if(x - 1 >= 0) {
    if(pixelVals[x - 1][y][0] != 255) {
      if(!checkedPixels[x - 1][y]) {
        checkSurroundings(x - 1, y)
      }
    }
  }
  if(y + 1 < height) {
    if(pixelVals[x][y + 1][0] != 255) {
      if(!checkedPixels[x][y + 1]) {
        checkSurroundings(x, y + 1)
      }
    }
  }
  if(y - 1 >= 0) {
    if(pixelVals[x][y - 1][0] != 255) {
      if(!checkedPixels[x][y - 1]) {
        checkSurroundings(x, y - 1)
      }
    }
  }
}

function setFilled() {
  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      if(filledPixels[i][j]) {
        pixelVals[i][j][2] = 255;
      }
    }
  }
}

function setFilledFalse() {
  for(var i = 0; i < width; i++) {
    for(var j = 0; j < height; j++) {
      filledPixels[i][j] = false;
    }
  }
}

function array(length) {
  var arr = new Array(length || 0), i = length;

  if (arguments.length > 1) {
    var args = Array.prototype.slice.call(arguments, 1);
    while(i--) arr[length-1 - i] = array.apply(this, args);
  }
  return arr
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.js"></script>