1j01 / jspaint

🎨 Classic MS Paint, REVIVED + ✨Extras
https://jspaint.app/about
MIT License
7.22k stars 562 forks source link

Ovals are broken - literally! #158

Open 1j01 opened 4 years ago

1j01 commented 4 years ago

Ellipses are getting cut off slightly, depending on their size, ever since implementing them with webgl as polygons. Particularly, wide ovals.

image

Ellipses are drawn to a temporary canvas, and the bounds are not big enough to account for these quirky asymmetrical pixels jutting out of the bottom. Shown in the example image is also a tall oval, which has a horizontal tumor, but which is included in the bounds and thus rendered.

(Eventually it would be good to use a proper raster ellipse algorithm, that results in symmetrical ovals. It might make sense to still use WebGL to draw all at once for performance with large ovals, but generate the exact pixels for the border of the shape, for accuracy, just use them as vertices.)

1j01 commented 4 years ago

This may be OS/browser/GPU-specific.

Writing some automated tests for tools, here are some results I got: image (This doesn't mean you can't get broken circles on Windows or better circles on Linux.)

karabaja4 commented 3 years ago

Noticed this happens on NVIDIA propriatery blob drivers, but does not happen on Intel open source drivers on the same system (Arch Linux @ Chromium 88.0.4324.96). So apparently it's related to which GPU/driver is used.

OscarCasadoLorenzo commented 1 year ago

Hi @1j01, I have already being testing this issue with the next driver configuration, It does not seem drivers related answer will solve the problem. There it is the drivers of my VM: image And here the ones of the machine: image

Maybe checking ellipsis generator algorithm is the best way to fix it.

CarlosPovedaC commented 1 year ago

Hello. I have the same problem on a 2017 macbook pro with an AMD radeon pro 560 graphics card

Captura de Pantalla 2023-02-04 a las 22 59 05
OscarCasadoLorenzo commented 1 year ago

Like I previously suggested, it happens because of the algorithm of the ellipsis (and rounded square too).

Explanation: In your code there was a variable related to aliasing (the one you use to determine if the strokes of the shapes should be softened)... let aliasing = true; //app.js:10

At image-manipulation.js file, the conditions under you apply aliasing and anti-aliasing algorithms are uncomplete, because the ´if´ interpolation algorithm is not suitable with small strokes, like the one that you applies by default (1px), there is the explanation of why at your tests there is no differences between shapes of third and fourth rows.

To sum up, you have two ways to solve it:

  1. Consider the stroke value to apply the best suitable algorithm, like the PR #316 that I propose: if (aliasing && stroke > MINIMUN_STROKE_SIZE_TO_APPLY_ALIASING)
  2. Refactor your aliasing algorithm using Breseham mathematical approach.

Considerations before PR: Using 'Fill with Color' bucket tool over one of this ellipsis will fill the full document because the errors caused by the delimiter stroke aproximations.