I have been attempting to create a flood fill function using an initial mouseX and mouseY value. After experimenting and failing with a 4 way recursive method I found an article that suggested using an array to store the 4 way values and queue them using the .push() function. While the array has values the function would then use the .pop()function to set new values to the x and y which in turn tested and changed to the desired colour.
After attempting this method for a flood fill I am still struggling to gain any sort of performance with regards to the speed. I tried to include an additional check history function to store the history of the visited pixels and prevent any repeated x,y coordinates from being pushed back into the queue. however (when using the console to log "match found") the function appears to not find any repetitions.
I would really appreciate any guidance on how to improve upon the code I have written so far. Or perhaps a suggestion on a different method that is not to complicated to implement. I rarely use Stack Overflow and would also appreciate guidance on how to format questions and code for future reference. Thank you for any of your time.
using the sketch.js I have included, you can see that the fill function is acceptable on very small objects(the first initial square), but as the size increases the performance grinds to halt.
index.html
<!DOCTYPE html>
<html>
<head>
<script src="p5.min.js"></script>
<script src="sketch.js"></script>
<style> body {padding: 0; margin: 0;} </style>
</head>
<body>
</body>
</html>
sketch.js
var colorNew = [0,255,0,255];
function setup()
{
createCanvas(500,500);
squares();
}
function squares(){
background(255);
noFill();
stroke(0);
rect(125,125,10,10);
rect(125,125,20,20);
rect(125,125,30,30);
rect(125,125,40,40);
rect(125,125,50,50);
updatePixels();
}
function getPixData(xPos,yPos){
colorOld = get(xPos,yPos);
};
function checkValue(xPos,yPos,oldColor){
var currentPix
currentPix = get(xPos,yPos);
if(currentPix[0] == oldColor[0] && currentPix[1] == oldColor[1] && currentPix[2] == oldColor[2] && currentPix[3] == oldColor[3]){
return true;
}
};
function checkHistory(x1,y1,historyArray){
for (var i = 0 ; i < historyArray.length; i+=2){
if(x1 == historyArray[i] && y1 == historyArray[i+1]){
console.log("match found");
return false;
}else {
console.log(historyArray.length)
return true;
}
}
};
function floodFill (xPos,yPos){
getPixData(mouseX,mouseY);
var stack = [];
var historyList = [];
stack.push(xPos,yPos);
historyList.push(xPos,yPos);
console.log(stack);
while(stack.length> 0){
var yPos1 = stack.pop();
var xPos1 = stack.pop();
set(xPos1,yPos1,colorNew);
updatePixels();
if(xPos1+1 <= width && xPos1+1 > 0 ){
if(checkValue(xPos1+1,yPos1,colorOld) && checkHistory(xPos1+1,yPos1,historyList)){
stack.push(xPos1+1,yPos1);
historyList.push(xPos1+1,yPos1);
console.log("right checked")
}
}
if(xPos1+1 <= width && xPos1+1 > 0 ){
if(checkValue(xPos1-1,yPos1,colorOld) && checkHistory(xPos1-1,yPos1,historyList)){
stack.push(xPos1-1,yPos1);
historyList.push(xPos1-1,yPos1);
console.log("left checked");
}
}
if(yPos1+1 <= height && yPos1+1 > 0 ){
if(checkValue(xPos1,yPos1+1,colorOld) && checkHistory(xPos1,yPos1+1,historyList)){
stack.push(xPos1,yPos1+1);
historyList.push(xPos1,yPos1+1);
console.log("above checked");
}
}
if(yPos1-1 <= height && yPos1-1 > 0 ){
if(checkValue(xPos1,yPos1-1,colorOld) && checkHistory(xPos1,yPos1-1,historyList)){
stack.push(xPos1,yPos1-1);
historyList.push(xPos1,yPos1-1);
console.log("below checked");
}
}
}
console.log(historyList);
}
function draw()
{
if(mouseIsPressed){
floodFill(mouseX,mouseY)
}
}