Jump to content

Why are aliased rounded rectangles so uneven?


Recommended Posts

A 20x20 rounded rectangle with border width 1 and corner radius 4 looks like this:

image.png.8d6556a583b45c645c3256e55265da47.png

For some reason, 3 out of 4 corners get a "different" version of how a rounded corner looks like; only the top right seems to be actually 4x4.

 

This is what radius 5 looks like:

image.png.536119c0ee32d84596099c3b8449cc54.png

None of these corners have a 5x5 footprint.

 

Here's radius 6:

image.png.82a7210be8cd3c73a218679d3a206dcf.png

You get the idea...

 

I tested all values from 1 to 10, and none of these values resulted in a symmetrical shape.

I'm not sure it has always been like this, or if that's a regression, but something's odd about the rounding here, resulting in that I effectively cannot use this tool unless I want to check and tidy up 3 or all 4 corners, which may be feasible for radii up to 8, but beyond that it's very cumbersome.

Link to comment
Share on other sites

19 hours ago, BoltBait said:

Paint.NET uses Direct2D for drawing primitives.  So, take this up with Microsoft.

 

Okay, so from what I have read here, the issue seems to be that PDN is using Direct2D for drawing shapes, and while the antialiased version are good, the aliased geometry is poor and that causes the problem. What's really interesting is that this only happens at thickness 1. Thickness 2 seems to be symmetrical for non-rotated shapes.

Link to comment
Share on other sites

I have created a proof of concept for a custom renderer that handles circles, ellipses, and rounded rectangles. There is not yet any ability to rotate a shape and to be fair that is something I haven't even gotten around to think about.

 

@Rick Brewster I published the code under MIT license. If you want to take a look, or use my code (or the "thickness = 1" bits) as base for your own custom renderer that you have not gotten around to since 2010, feel free. Also, if you want me to strip the code to only the "thickness = 1" case first, and/or want to see inclusion of rotations as well, please let me know.

  • You're a Smart Cookie! 1
Link to comment
Share on other sites

On 10/5/2023 at 8:25 AM, BoltBait said:

Paint.NET uses Direct2D for drawing primitives.  So, take this up with Microsoft.

 

For 1-px brush width, without antialiasing, I use my own renderer because Direct2D does a bad job there. So there's precedent for something like this.

 

Every time I've looked at this problem, it just was not simple to solve despite seeming like it should be.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

9 hours ago, BoltBait said:

 

Render 1/4 of the shape (upper left), mirror and flip?

 

That's also how I do it in the PoC. What I find difficult about this is - how would you implement rotation? Because for a rotated ellipse for example, "top left" of input can't be "easily" reflected (or at least I wouldn't trust that mathematical calculations of reflected pixels about a randomly slanted symmetry axis will never ever create a result with a gap in the outline), and for output the "top left" isn't enough and also potentially not a rectangle.

 

Sadly, I noticed it's not necessarily limited to 1px outlines if you consider rotation. This is how a 34x11 ellipsis with border thickness 2 looks like when rotated exactly 90°:

image.png.bfc786d0936e8a78c66733086ce1e4e3.png

While doing this example, I also noticed that in PDN, the outline of ellipses grow symmetrically around the set size.


E. g. for a 20x20 rectangle with border thickness 6, all border pixels lie within that 20x20 (the fill is 8x8).
But switch to ellipse, and now 3 pixels are inside, 3 are outside, meaning the resulting shape is actually 26x26 in size.

image.png.db1b678d6a71c35e5b51643420370250.png

However don't think changing that to a consistent behavior (where I prefer the rectangle one) would be detrimental to anyone (except for that one person drawing ellipses using an AutoHotkey macro on a daily basis).

 

[Edit: I now realized that "rectangle" and "rounded rectangle" are the outliers here; all other shapes grow symmetrically around the set size, only those two grow within. I still like the rectangle's behavior better, because it preserves size while changing outline thickness or form fill mode from :ShapeDrawTypeOutline: to :ShapeDrawTypeInterior:]

Edited by LWChris
Link to comment
Share on other sites

22 hours ago, BoltBait said:


Render top left to a buffer. From that, draw full shape to buffer. In a separate step, rotate buffer to image using nearest neighbor. 

 

No, that would produce awful results

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...