1
\$\begingroup\$

I have a pixel art brush and a canvas. When the brush size is 3, I want to draw a cross shape instead of a 3x3 square.

I implemented the following formula: if the distance between two points is less than or equal to the radius, paint in the pixel.

The problem is, the distance between the center point and the corner pixel is sqrt(2), or 1.4, while the radius is 1.5. I am not sure how to solve this.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Look:

Circle of 1.5 radius over-imposed on a 3 by 3 grid

Here you see a Circle of 1.5 radius. So it barely touches the outside of the 3 by 3 grid.

Now, you are checking a point that is (1, 1) from the center of the circle. Where is that? That is the center of one of the corner cells of the 3 by 3 grid. And yes, that point is inside the circle.

Notice that only the center cell is fully inside the circle.

You want some criteria that will include the side cells but not the corner cells (making a cross). Well, observe that:

  • Most of the corner cell is outside.
  • Only one of the corners of the corner cell is inside. But the side cells have two corners inside.

Checking corners of the cell is easier. You would check four points for the cell:

  • (0.5, 0.5) from the center, which is inside (distance is 0.707107... < 0.5).
  • (1.5, 0.5) from the center, which is outside (distance is 1.58114... > 0.5).
  • (0.5, 1.5) from the center, which is outside (distance is 1.58114... > 0.5).
  • (1.5, 1.5) from the center, which is outside (distance is 2.12132... > 0.5).

Checking how much of the cell is inside is harder, but also more interesting, because you could use it to shade the cells proportionally.

You can reach an approximation by checking an array of points inside of the cell. In fact, checking the four corners is a first approximation.

But we can do better by cutting some corners. Once you know which corners are inside, you also know which sides does the circle cut. Then by computing the intersection of the circle with the sides, you can get this approximation:

Red octagon over-imposed on a circle of 1.5 radius over-imposed on a 3 by 3 grid

You would have to identify which case it is based on which corners are inside. The area inside the segments drawn should be simple to compute. And the missing area is a circular segment, so you can apply the formula for that.


I doubt you would need to go into figuring out how much of each pixel is inside the circle for your use case. Checking the corners should be sufficient.

You might also be interested in Midpoint circle algorithm, Marching squares.

\$\endgroup\$
1
  • \$\begingroup\$ Thank you for the answer! I was afraid that I would have to do integration based on some other questions I found. \$\endgroup\$ Jun 9 at 13:56
0
\$\begingroup\$

One thing you could do is continue to use the formula you currently are, but tweak the radii. For example, a circle of diameter 2 (radius 1), or anywhere between radius 1 and radius \$\sqrt{2}\$, will hit exactly the pixels you want, if properly centered:

Circle of radius 2 centered on a pixel

Subtracting 1 will not be desirable for arbitrarily large circles since it would lead to them always having a 1-pixel nub on 4 sides, but perhaps you could subtract 0.5, or have a table of “fudge factors” applied to specific very small circle sizes, set to whatever makes each size look good.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .