Is there a more optimal way to choose lines than the Bresenham algorithm?

In my HTML canvas project, I am currently drawing lines using a 2d-array that represents blocks of 10x10 pixels. I use Bresenham's algorithm to store line-ids in this array so that I can determine which line is selected.

While this method works, I find that it lacks precision. When I overlay a representation of the array on my canvas, I notice that many of the 10x10 blocks are not completely filled even though the line crosses them:

Is there a more accurate solution to ensure that all grid blocks the actual line passes through are captured?

Answer №1

It seems like there may have been a mistake in the rounding process when populating the lookup table using the Bresenham algorithm, or perhaps the coordinates were scaled incorrectly before executing the algorithm.

You can view my solution and see that the squares are perfectly aligned in this jsFiddle.

HTML

<canvas id="myCanvas"></canvas>

CSS

#myCanvas {
    width: 250px;
    height: 250px;
}

JavaScript

var $canvas = $("#myCanvas"),
    ctx = $canvas[0].getContext("2d");

// Remaining JavaScript code for grid creation, line rendering, and event handling...

Answer №2

Consider the mouse cursor position as a miniature circle, such as one with a 5px radius, and determine if it intersects with the line.

Refer to this Q&A for the mathematical explanation.

JavaScript

A basic function to identify intersection:

function lineCircleIntersects(x1, y1, x2, y2, cx, cy, cr) {
    var dx = x2 - x1,
        dy = y2 - y1,
        a = dx * dx + dy * dy,
        b = 2 * (dx * (x1 - cx) + dy * (y1 - cy)),
        c = cx * cx + cy * cy,
        bb4ac;

    c += x1 * x1 + y1 * y1;
    c -= 2 * (cx * x1 + cy * y1);
    c -= cr * cr;
    bb4ac = b * b - 4 * a * c;

    return bb4ac >= 0;  // true: collision, false: no collision
}

View it in action on this jsFiddle, but be aware that this function may also indicate a collision if the cursor lies on the line's slope outside [x1, y1], [x2, y2]. This decision is yours to make :)

You can explore the line-circle-collision library on GitHub for further assistance.

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

Leveraging the combination of <Form>, jQuery, Sequelize, and SQL for authentication and navigation tasks

My objective is to extract the values from the IDs #username-l and #pwd-l in an HTML form upon the user clicking the submit button. I aim to compare these values with those stored in a SQL database, and if they match exactly, redirect the user to a specifi ...

leveraging dependency injection to retrieve a function in JavaScript

I'm exploring a way to obtain a function in JavaScript without executing it, but still defining the parameters. My current project involves creating a basic version of Angular's dependency injection system using Node.js. The inject() method is us ...

Instructions on how to activate scrolling for a div element that becomes visible upon clicking a button

When a button in the navbar is clicked, a div appears with a height that exceeds the viewport/page size. How can I enable scrolling for the entire page when this happens? I attempted to use overflow: scroll, but it only applied scrolling to the internal d ...

listening for events on nested classes

I am looking to dynamically toggle the class "collapsed" on each element with the class "category" when it is clicked. The issue arises when these "category" elements are nested within each other, causing the child elements to also trigger the class change ...

Add integer to an array of strings

Currently, I am utilizing an autocomplete feature and aiming to save the IDs of the selected users. My goal is to store these IDs in a string array, ensuring that all values are unique with no duplicates. I have attempted to push and convert the values u ...

How can strings of dates be arranged in MM/DD/YYYY order?

Is there a correct way to sort these dates in descending order? I've attempted using arr.sort() and arr.sort().reverse(), searched extensively on stack overflow, but still cannot find a solution. Every attempt at sorting them seems to be incorrect. [ ...

Define the content and appearance of the TD element located at the x (column) and y (row) coordinates within a table

In my database, I have stored the row and column as X and Y coordinates. Is there a straightforward way to write code that can update the text in a specific td element within a table? Here is what I attempted: $('#sTab tr:eq('racks[i].punkt.y&a ...

The error TS2339 is indicating that there is no property called myProperty on the type SetStateAction<User>

I'm encountering a TypeScript error while working with React that's leaving me puzzled: <html>TS2339: Property 'subEnd' does not exist on type 'SetStateAction&lt;User&gt;'.<br/>Property 'subEnd' d ...

It can be challenging to manage numerous if-else conditions in JQuery

I am having trouble with my JQuery code that checks multiple conditions. No matter what I enter, it always goes to the else condition. $(function() { $('#installment').on("keydown keyup", check); function check() { var inst = Number($( ...

Tips for handling a JSON payload retrieved through a POST request

I'm currently working on a button that triggers a POST call to retrieve a json response from the server. My goal is to display this json response in a new (chrome) browser tab. Here's what I have so far using Angular: $http.post(url, data) .t ...

Bypass license and credit comments when compressing JavaScript with YUIcompressor

When using YUICompressor to minify JavaScript, is there a method to retain license or credit comments? Are there specific commenting characters to use, or a flag in YUICompressor for this purpose? Thank you, Grace ...

Is there a possibility of encountering an endless update loop within a component's render function?

Hello! I am a beginner in Vue.js and I have encountered an issue with my function. Instead of increasing my variable to 1 as expected, it is increasing it to a random number every time. The console is displaying the following error message: "You may hav ...

Webpack in Vuejs does not have access to the keys defined in dev.env.js file

The framework utilized here is vuejs-webpack, with build and config files located here. No modifications have been made to these files. According to the information on Environment Variables, the keys specified in dev.env.js should be accessible during the ...

What is the best way to trigger an event in VueJS?

I recently implemented a table using Vuetify in my project. The table is now split into two components - the Table component and the Row component. My challenge is how to handle the same function, this.selected = !this.selected!, when dealing with 2 differ ...

Display array values in JavaScript from different arrays

I'm currently working on extracting data from my API to plot it in a graph. Specifically, I am interested in obtaining an array that contains only the 'date' values. Here's what I have managed to extract so far: This is the code snippe ...

Issues with triggering the success block in AngularJS and Node.js Express when using $http.get

As a beginner in the world of AngularJS and Node.js, I'm facing an issue with my $http.get method. The problem is that the success callback block does not get executed when the request is successful, whereas the error callback works just fine when the ...

Activate the Keypress event to update the input value in React upon pressing the Enter

I am facing an issue where I need to reset the value of an input using a method triggered by onPressEnter. Here is the input code: <Input type="text" placeholder="new account" onPressEnter={(event) => this.onCreateAccount(event)}> < ...

JavaScript - Retrieve the name of an object from a separate array

Is it possible to dynamically map rows and columns in a table component using arrays of objects? For example, I have two arrays of objects like this: const columnData = [ { id: 'name', label: 'Name' }, { id: 'value', lab ...

Conceal or remove disabled years in Angular Material datepicker

I previously disabled years prior to 2018, but now I would like to hide or delete them. The year selection range currently starts from 1998, but it should begin at 2018 instead. Is there a way to display only 3-4 years instead of the current 24-year rang ...

Personalize Badge Component

I've been on the hunt for a solution to customize a badge component similar to what's seen here: https://mui.com/material-ui/react-badge/. As of now, only options for making it a dot or adding a number in a circle are available. However, I' ...