Challenges in implementing floodfill algorithm pseudocode

I've been working on implementing the flood fill algorithm pseudocode that I found in Graphics Gemes 1.
Here is the pseudocode:

https://i.stack.imgur.com/X6jV4.png

Unfortunately, when I translated it to JavaScript and used my floodfill tool, it caused my code to hang. Here's a snippet of the code I used:

function inside(x, y) {
    const q = 4 * (x + y * that.w);
    const color = [img.data[q], img.data[q + 1], img.data[q + 2], img.data[q + 3]];
    return color[0] === toolColor[0] &&
        color[1] === toolColor[1] &&
        color[2] === toolColor[2];
}

function set(x, y) {
    const q = 4 * (x + y * that.w);
    img.data[q] = that.color.r;
    img.data[q + 1] = that.color.g;
    img.data[q + 2] = that.color.b;
    img.data[q + 3] = that.color.a;
}

// More code....

<p><code>img.data is an array displayed in the browser.
toolColor contains the colors for the area to be filled.
I'm struggling with why the algorithm only fills part of the area.
If you need more code details, feel free to ask.

Edit: After some updates, the code now partially fills the area.
https://i.stack.imgur.com/THPTh.png

Answer №1

After some modifications, the code is now optimized for speed. Hopefully, it can be useful to someone.

Check out the updated code below:

function inside(x, y) {
    const q = 4 * (x + y * that.w);
    const color = [img.data[q], img.data[q + 1], img.data[q + 2], img.data[q + 3]];
    return color[0] === toolColor[0] &&
        color[1] === toolColor[1] &&
        color[2] === toolColor[2];
}

function set(x, y) {
    const q = 4 * (x + y * that.w);
    img.data[q] = that.color.r;
    img.data[q + 1] = that.color.g;
    img.data[q + 2] = that.color.b;
    img.data[q + 3] = that.color.a;
}

function doFloodFill(x, y) {
    let skip = false, x1, x2, dy, start;
    const s = [];

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

    while (s.length > 0) {
        const n = s.pop();
        y = n[3] + n[0];
        x1 = n[1];
        x2 = n[2];
        dy = n[3];
        x = x1;
        while (x >= 0 && inside(x, y)) {
            set(x, y);
            x--;
        }
        if (x >= x1) {
            //skip
            skip = true;
        }
        if (!skip) {
            start = x + 1;
            if (start < x1) {
                s.push([y, start, x1 - 1, -dy]);
            }
            x = x1 + 1;
        }
        do {
            if (!skip) {
                while (x <= that.w && inside(x, y)) {
                    set(x, y);
                    x++;
                }
                s.push([y, start, x - 1, dy]);
                if (x > x2 + 1) {
                    s.push([y, x2 + 1, x - 1, -dy]);
                }
            }
            //skip
            x++;
            while (x <= x2 && !inside(x, y)) {
                x++;
            }
            start = x;
            skip = false;
        } while (x < x2);
    }
}

There was a minor error in the previous version. The skip value should have been within the last loop instead of outside.

In addition, the initialization of the y value in the loop was incorrect. It should be: y = n[3] + n[0]; rather than y = n[0];

It seems that the code on English Wikipedia regarding this algorithm may contain inaccuracies.

I conducted speed tests on this algorithm. My implementation performs approximately 1.5 times faster compared to the code found on Wikipedia.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Implementing a comment system using Node.js and MySQL: A comprehensive guide

Hey there! I have some data that I want to use to create a hierarchical data example. { id_commentForum: 1, id_user: 1, id_thread: 1, comment: 'This is the First Comment', parent: 0, created_at: Wed Jun 22 2016 13:36:38 G ...

Exploring the connections between Ajax, asp.net mvc3 routing, and navigating relative URLs

My ASP.NET MVC3 application is live at a URL like this: http://servername.com/Applications/ApplicationName/ In my code, I am making jQuery AJAX requests in this manner: $.get(('a/b/c'), function (data) {}, "json"); When running the applicati ...

Apply Jquery to add emphasis to every item on the list

Can someone help me with this assignment? I need to create a jQuery function that italicizes all list elements on the page when triggered by the client. Here is my current approach: $(document).ready(function() { $("li").click(function() { ...

Altering the backdrop upon hovering over an element

As a beginner in Javascript and Jquery, I am working on creating an interactive feature where hovering over one element changes the background image in another column. I have managed to write the function, but now I want to add an animation to the image tr ...

Are there any other options similar to PhantomJs that offer support for CSS 3D effects?

I am working on capturing a webpage using NodeJs. My current setup involves using PhantomJs to capture screenshots of the page and ffmpeg to convert them into videos. However, I have encountered an issue where the page contains 3D transform CSS, which is n ...

displaying 'undefined' upon completion of iterating through a JSON file using $.each

For my project, I am attempting to extract only the date data from a JSON object. I have successfully looped through the object and displayed it, but the issue arises at the end of the loop where it shows undefined. I am not sure what mistake I am making. ...

Transferring data from a callback function within a component to a different component

I am currently utilizing the giphy-api module in Node.js and I need to transfer this data to React. Within my setup, I have two key components: The first component, Api.js, effectively connects with Node.js and returns a callback containing all of the AP ...

Encountering Internal Server Error when running Node-Express app on render.com with query parameters live

Currently, I am facing an issue while attempting to execute a live route with query using my nodejs express application on render.com. Strangely, all other routes connected to the crud operations are functioning properly except for the search filter route ...

ReactJS: Dealing with issues in setting a dynamic index for the setState key

I have been attempting to utilize setState within a for loop using index in the following manner: for (var i = 0; i <= 9; i++) { this.setState({ location_option[i]: resourceData.location_option+i, location_option[i]_type: resourceData.locatio ...

Delay the next loop iteration until receiving an HTTP request

I have a task where I am collecting YouTube video IDs and storing them in an array. Then, I am looping through each video ID to determine the size of that ID's thumbnail image. My challenge now is making sure my loop waits for the HTTP request to fini ...

Using React.js to select and change the color of an element

I'm developing a movie theater app, in which I am building a feature to select seats in the cinema hall and add them to the cart. Here is the function that displays the cinema hall: export default function CinemaHall(props) { const row = props.row ...

How to find the length of an array in Node.js without utilizing JQuery

Is it possible to determine the length of the Dimensions array in nodejs? The array can have 1 or 2 blocks, and I need to write an if condition based on this length. Since this code is inside an AWS-Lambda function, using JQ may not be an option. For exam ...

Keycloak does not support using the updateToken() function within an asynchronous function

In our development of a Spring application with React/Redux frontend, we faced an issue with Keycloak authentication service. The problem arose when the access token expired and caused unexpected behavior in our restMiddleware setup. Here is a simplified v ...

Updating a property on an object during iteration

Currently, I am in the process of developing a Single Page Application using Laravel on the backend and Vue.js. I have two arrays that are crucial to my project: The first array is accessArray: ["BIU","CEO","Finance","HRD","Group"] The second array is a ...

Troubleshooting the onExited callback issue with Popover component in Material UI

<Popover key={element.name} classes={{ paper: classes.paper }} open={open} anchorEl={this.myRef.current} anchorOrigin={{ vertical: ' ...

Is it possible to implement a custom sign-in form for AWS Cognito?

Is it possible to replace the AWS Cognito hosted UI with a custom form in my Next.js app that utilizes AWS Cognito for authentication? import { Domain } from "@material-ui/icons"; import NextAuth from "next-auth"; import Providers fro ...

Obtaining Input Field Value in Angular Using Code

How can I pass input values to a function in order to trigger an alert? Check out the HTML code below: <div class="container p-5 "> <input #titleInput *ngIf="isClicked" type="text" class="col-4"><br& ...

Implementing a Vue.js v-bind:style attribute onto a dynamically generated element post-page initialization

Let me start by explaining my current issue and dilemma: I have been tasked with converting an existing JS project into a Vue.js framework. While I could easily solve a particular problem using jQuery, it seems to be posing quite a challenge when it comes ...

Exploring the functionality of placeholders within jQuery

I am trying to create a customizable text template where I can insert placeholders and then fill those placeholders with data to use on my page. For example: var template = '<div class="persons">'; template += '<p> <span clas ...

Passport JS allows you to create a secure login form that redirects users to different URIs based on their role

Currently, I am utilizing Passport JS for authentication management and Express JS to handle routing within my application. At the moment, I have a login route that directs to the /teacher URI upon successful authentication (as depicted below). app.post( ...