Flood Fill Algorithm- only coloring outside of the area trying to be filled

64 Views Asked by At

I was following a tutorial (https://www.youtube.com/watch?v=a7qCVxq-dWE) about implementing a flood fill algorithm and I thought my code looked exactly the same as the person I was following but mine is not working and his is. The outside of the circles I am drawing get filled and the inside stays white for some reason. And then I can't fill multiple circles/other drawings. I am pretty new coding and some of this is a bit beyond me and I'm sure there is a better or more efficient way to implement flood fill but this was the most detailed tutorial I came across. Thanks

I have looked back at the tutorial and I cannot tell what is different but this is my code so far and an image of what is happening and what should be happening. Thank you!

let imageData;

function setup() {
  createCanvas(1000, 1000);
}

function draw() {
  drawing();
}

function drawing() {
  if (mouseIsPressed) {
    line(pmouseX, pmouseY, mouseX, mouseY);
  }
}

function keyPressed() {
  imageData = drawingContext.getImageData(0, 0, 1000, 1000);
  floodFilling(mouseX, mouseY);
  drawingContext.putImageData(imageData, 0, 0);
}

function floodFilling(x, y) {
  let fillStack = [];
  fillStack.push([x, y]);

  while (fillStack.length > 0) {
    let [x, y] = fillStack.pop();
    if (!valid(x, y)) 
      continue;
  
      if (isPixel(x, y)) 
        continue;
      
    }
  }

    setPixel(x, y);

    fillStack.push([x + 1, y]);
    fillStack.push([x - 1, y]);
    fillStack.push([x, y - 1]);
    fillStack.push([x, y + 1]);
  }
}

//set color of pixel
function setPixel(x, y) {
  let pixels = imageData.data;

  let i = (y * width + x) * 4;

  pixels[i] = 255;
  pixels[i + 1] = 0;
  pixels[i + 2] = 0;
  pixels[i + 3] = 255;

}

//make sure it has color
function isPixel(x, y) {
    let pixels = imageData.data;

    let i = (y * width + x) * 4;

    return pixels[i + 3] > 0;
}

//make sure it is in bounds of canvas
function valid(x, y) {
  return x >= 0 && x <= width - 1 && y >= 0 && y <= height - 1;
}
[[the problem/what should be happening](https://i.stack.imgur.com/XOwYB.png)](https://i.stack.imgur.com/LNLeV.png)```
1

There are 1 best solutions below

1
apodidae On

I was unable to run the code that you posted due to code block errors. The following source code will run, but not the way that the original author intended. The exact same thing happened to my personal copy when I tried to follow along with his video presentation. The only possible explanation that I can think of is that he used a different editor or browser. I used p5.js Web Editor in a Chrome browser on a Mac. The background is colored red when a key is pressed instead of the inside of the shape as he intended. It did work correctly with his setup, but not with mine and apparently not with yours either.

let imageData;

function setup() {
  createCanvas(1000, 1000);
  pixelDensity(1); // The fix
}

function draw() {
  if (mouseIsPressed) {
    line(floor(pmouseX), floor(pmouseY), floor(mouseX), floor(mouseY));
  }
}

function keyPressed() {
  imageData = drawingContext.getImageData(0, 0, 1000, 1000);
  floodFill(floor(mouseX), floor(mouseY));
  drawingContext.putImageData(imageData, 0, 0);
}

function floodFill(x, y) {
  let fillStack = [];
  fillStack.push([x, y]);
  while (fillStack.length > 0) {
    let [x, y] = fillStack.pop();
    if (!valid(x, y)) continue;
    if (isPixel(x, y)) continue;

    setPixel(x, y);

    fillStack.push([x + 1, y]);
    fillStack.push([x - 1, y]);
    fillStack.push([x, y - 1]);
    fillStack.push([x, y + 1]);
  }
}

//set color of pixel
function setPixel(x, y) {
  let pixels = imageData.data;
  let i = (y * width + x) * 4;

  pixels[i] = 255;
  pixels[i + 1] = 0;
  pixels[i + 2] = 0;
  pixels[i + 3] = 255;
}

//make sure it has color
function isPixel(x, y) {
  let pixels = imageData.data;
  let i = (y * width + x) * 4;
  return pixels[i + 3] > 0;
}

//make sure it is in bounds of canvas
function valid(x, y) {
  return x >= 0 && x <= width - 1 && y >= 0 && y <= height - 1;
}

Addendum:

Recently discussed in another forum. Adding 'pixelDensity(1)' to the setup() fixes it. According to documentation this turns off pixelDensity().