Jump to content

Using shapes


Recommended Posts

Using shapes, I can easily create a circle, but how to make a perfect circle? As I drag it to the size I want, I can only get it eye-ball right. Is there a way to preserve the same heighth and width so as to create a true circle, not an ellipse?

 

Also, If I want two circles to be concentric, is there a way to do this, other than eye-ball close?

 

Other than these two issues, paint.net is the most amazing program I have come across. I should mention I am using 4.0

Edited by chameleongeorge
Link to comment
Share on other sites

As long as we're talking about circles, I've found that single pixel, non-anti-aliased circles of small size look terrible. This is probably due to how the circle's coordinates are mapped to the pixel's coordinates, as obviously thicker and/or anti-aliased circles look better, but I thought I would mention it.

Link to comment
Share on other sites

Aliased ellipses are currently awful, very true. They also weren't symmetric in 3.5 or earlier versions. And, surprisingly, they aren't in regular MSPaint either!

 

I was able to get antialiased ellipses to be symmetric (huzzah!), but it took a pretty big performance hit to do so.  Direct2D is built on top of Direct3D, so any geometry it renders has to be broken down into lines and/or triangles (for filling). By default it uses some settings for converting an ellipse into a list of lines (aka a polygon) that balances performance with image quality (in this case, symmetry). To be specific, it uses a flattening tolerance value of 0.25 which means it'll have a maximum of 0.25 pixels between line segment points (I may be slightly off with that definition). I had to change that value to 0.0001 in order to get symmetry, which means it's emitting up to 2,500 times more line segments (I may be off with my math but the general idea is the same: at least an order of magnitude more involved!). Unfortunately, this still didn't help aliased ellipses, and I couldn't justify spending the time to fix that right before the 4.0 release (it was really frustrating and I was at wit's end).

 

I even had to write my own custom rasterizer for the 1 pixel aliased case, otherwise I had even worse rendering with both extra and MISSING pixels. Imagine drawing a straight line and having it skip pixels every once in awhile. I'm not sure what they're smoking over there in Direct2D land but I'd really like to get my hands on it. I'll likely have to special-case all aliased ellipse rendering.

 

The good news it that while fixing the bug in the brush tools where drawing at size = 3 looks the same as size = 2 (and, really, all odd sizes are basically truncated to the even number below them), I discovered that Direct2D is in fact capable of filling an aliased ellipse with symmetry. That's a good step in the right direction at least.

  • Upvote 4

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

As long as we're talking about circles, I've found that single pixel, non-anti-aliased circles of small size look terrible. This is probably due to how the circle's coordinates are mapped to the pixel's coordinates, as obviously thicker and/or anti-aliased circles look better, but I thought I would mention it.

 

I'm not sure how techy you are, but I'm not techy at all. So I found this video kind of nice, it's about pixels and anti-aliasing : http://www.youtube.com/watch?v=hqi0114mwtY

Edited by Cc4FuzzyHuggles
Link to comment
Share on other sites

Ha, see, this is where my knowledge of math and my knowledge of programming and rendering drop completely apart.

I always thought it was weird that drawing programs basically draw the circle outside-in* rather than inside-out. I always thought it made more sense to start at the center, pull the cursor out in any direction to define the radius, and then define the circle that way. If this were the method, I would personally prefer ellipses to be drawn in a two-step process, defining the foci first and then a point on the radius; this would allow rotated ellipses without needing to actually rotate them. However, this is just me musing over the formulae for circles and ellipses in my head; so pay no mind.

 

What I DO get is what you are saying about polygons; I personally have done the math to derive radius/area formulae from triangles and surface area/spherical volume formulae from pyramids (yes, sometimes in math class I wanted to know why something was the way it was!) so I am all too familiar how data points and calculations rise rapidly with slight increases in precision.

 

Pardon my ignorance in the mechanics of the issue (ESPECIALLY if this is already what is going on!) but would it be helpful to define the ellipse dynamically as it is sized, perhaps with a # of line endpoints related to the size of the ellipse at any given moment (thus allowing smoother curves when needed with bigger objects) and then processing the actual pixels/lines to be drawn completely only once the mouse button is released (perhaps only showing the line endpoints, or an approximate until then)? Or, to draw it by formula while it is being sized, appearance be damned, but have it "refined" once the button is released?

In any case, it's good enough for me right now, I work mostly in small scale so I can work fine with approximates that I can adjust after. But it would be interesting to see what comes up in the future.

 

*That is, the first point chosen is on the radius, not the center.

Edited by Japhasca
Link to comment
Share on other sites

I even had to write my own custom rasterizer for the 1 pixel aliased case, otherwise I had even worse rendering with both extra and MISSING pixels. Imagine drawing a straight line and having it skip pixels every once in awhile. I'm not sure what they're smoking over there in Direct2D land but I'd really like to get my hands on it.

I completely understand. I was seeing the same issues so I wrote my own line drawing routine for the Render > Stars plugin I mentioned above. You can see it in action if you change the line width to 1 and disable anti-aliasing.

VariousShapes-1.gif

Here is the code I used:

// GDI sucks at drawing lines of brush width 1, so I'll do this job myself.
private void DrawThinLine(int x1, int y1, int x2, int y2, Surface dst, ColorBgra LineColor, PdnRegion selectionRegion)
{
    int i;
    double roundx, roundy, xi, yi, dx, dy, x, y, l;

    dx = x2 - x1;
    dy = y2 - y1;

    if (Math.Abs(dx) > Math.Abs(dy))
    {
        l = dx;
    }
    else
    {
        l = dy;
    }

    if (l < 0)
    {
        DrawThinLine(x2, y2, x1, y1, dst, LineColor, selectionRegion);
    }
    else
    {
        xi = dx / l;
        yi = dy / l;

        x = x1;
        y = y1;

        dst[(int)x, (int)y] = LineColor;
        
        for (i = 1; i <= l; i++)
        {
            if (IsCancelRequested) return;
            x = x + xi;
            y = y + yi;

            roundx = x + 0.5;
            roundy = y + 0.5;
            dst[(int)roundx, (int)roundy] = LineColor;
        }
    }
}
Hmmm... why did I send in a PdnRegion? Looking at the code now, I think it may write over the same pixels more than once since there is no clipping. Oh well, no harm done. ;)
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...