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: Ability to snap line tool to more angles · Issue #1641 · aseprite/aseprite · GitHub

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:
image

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.

I will try to show the problem with the “perfect blocks” pixel algorithm:

image

In all cases the lines are painted with a rectangle of 9x3 from top-left to bottom-right. The first case is the “perfect blocks” (3 blocks of 3x1 that makes the 9x3 line). If you see, the line itself is perfect, but these blocks cannot be put together to form a continuous line, e.g. Pencil tool, Shift+click to draw 3 lines of the same size/slope to continue the stroke).

In the second case (the current Aseprite algorithm, and most regular painting programs), you can see how the line looks uniform (the same process). But isolated it doesn’t make too much sense.

So, in the past we have used the “perfect blocks” but it brought this issue.

What can we do? Basically this cannot be solved automatically by an algorithm, it depends on the use case. Some users are expecting to draw regular continuous lines (Shift+clicking, or just using one end point as starting point of the next line), the current algorithm fits that case. And other users are expecting lines with “perfect blocks” (generally useful when drawing just one line or using as starting point the next expected point in the line).

At the moment the only way to use this “perfect blocks” mode in Aseprite is using Snap to Grid and configuring the grid appropriately:

image

We should offer an easier way to access to this functionality (maybe an option/checkbox in the context bar (“Pixel Perfect”?), or something like that for the Line tool).

1 Like

I have personally found use cases for the “imperfect” lines, so I agree that having a toggle for different line generation modes would be the best option :>

1 Like

Since the algo has already been done for Snap to Angle (holding Shift) and Snap to Grid it should be feasible to add an option, or modifier (Shift+Alt? but being too hidden = risk of being missed by users, so an option with a visible checkbox would be nice; or a combination of both option and temporary modifier key).

For fun I tried to set the Grip to 1px on X and Y and enable Snap to Grid, and it works: I can now press Shift+S to toggle snapping to grid and therefore perfect lines whenever I want.

image

However, Snap to Grid causes an unwanted effect:

  • when drawing toward the top or left, the first pixel is not confirmed: you need to start the line one grid cell earlier
  • when drawing toward the bottom or right, the last pixel is not confirmed: you need to move cursor past the last grid cell before releasing it

Polygon tool doesn’t have this issue but in counter part it tends to “fill” transitional pixels much more as if not following Pencil’s own pixel perfect mode (even though when using Snap to Grid, oddly enough the preview will pretend those extra pixels won’t be drawn, but they are).

These are other issues that I will open GitHub issues for, but that means even my workaround is not that simple to use.

EDIT: for the Polygon, I realised the issue is related to Polygon tool not support non-filled mode (see Draw just the outline of a polygon? - #2 by eishiya). Since it fills, when you draw a single line it will try to “close” the line which will add a few pixels.

EDIT 2: opened an issue for Line missing pixels issue: Snap Grid + draw Line causes first pixel to be missed when drawing toward top/left, last pixel to be missed when drawing toward bottom/right · Issue #4373 · aseprite/aseprite · GitHub