Line tool makes irregular lines

When using the line tool or shift+clicking with a brush, I expect the lines to be built out of segments that are as equally-sized as possible so that the lines appear as straight as possible, but Aseprite produces rather irregular lines:

Dark blue: correct line segments, where the length of the segment matches the expected segment length for that slope.
Red: incorrect/irregular line segments, shorter or longer than expected.

This makes the lines appear less straight than they could be, and I have to either hand-draw the line segments myself or edit Aseprite’s results to get straight, clean lines.

This appears to be a fairly common issue (I saw similar problems in GIMP, Photoshop, and Tiled) and I suspect it’s an artefact of Bresenham line algorithm’s error accumulation reaching the limit at weird times. For most slopes irregular line segments are to be expected so they’re less noticeable, but for lines like this, with 1:n or n:1 slopes, the irregularity is very noticeable, and makes a big difference for pixel art.

1 Like

Yeah it’s a problem with the line tool. Related issue:

I think rather than snapping to angles, I think a pixel-perfect mode for the line where it can only draw equal sized step lines would be a good solution.

1 Like

Hi there :wave: actually it was something I was playing a lot in the past, I came to the conclusion that the line algorithm used in most programs (including Aseprite now) is the best one (?) to draw continuous lines (e.g. the regular freehand stroke, or one line after the other). (Where the starting error of the Bresenham algorithm depends on the width+height of the line instead of starting in 0).

I think we need some kind of switch to use perfect lines or not in these cases.

A comment about the current line algorithm in the code:

// Useful to create continuous lines (you can draw from one point to
// another, and continue from that point to another in the same
// angle and the line will look continous).

Related to:

The lead dev of Tiled was working on this issue earlier (hearing about that is what prompted me to post this) and seems to have arrived at a rather good solution that changes the starting error based on the slope of the line:

The starting error change leads to the line halting early, hence the extension of the target y coordinate by 1.

I played around with it and I think the results are quite satisfactory:

Tiled’s algorithm deals with the error a little differently (and did so even before this change), but perhaps there’s something useful you can find in their code.