How to fill circle in Eric5h5's TextureDrawCircle function

Hi,

well I’m make a new version of that http://wiki.unity3d.com/index.php?title=TextureDrawCircle

function Circle (tex : Texture2D, cx : int, cy : int, r : int, col : Color) {

for(i = 0; i <= r; i++) {

var y = r - i;
var d = 1/4 - r;
var end = Mathf.Ceil(r/Mathf.Sqrt(2));

for (x = 0; x <= end; x++) {
	tex.SetPixel(cx+x, cy+y, col);
	tex.SetPixel(cx+x, cy-y, col);
	tex.SetPixel(cx-x, cy+y, col);
	tex.SetPixel(cx-x, cy-y, col);
	tex.SetPixel(cx+y, cy+x, col);
	tex.SetPixel(cx-y, cy+x, col);
	tex.SetPixel(cx+y, cy-x, col);
	tex.SetPixel(cx-y, cy-x, col);

	d += 2*x+1;
	if (d > 0) {
		d += 2 - 2*y--;
	}
		
}

}

}

I have a circumference, and I want to fill it for make a circle… I only have to substract one from the radius, and I will fill it, but:

Weird circle fill

It fills in a weird way…

so what can I do?

Thanks in advance.
Bye.

Nice. :slight_smile: It looks like classical spatial aliasing artifacts to me. It occurs because you’re trying to fill the circle by drawing concentric circles in pixel space from the center and outwards, one per radius, measured in pixels. But because pixels are inherently a discrete partitioning of the area of the circle, there will be pixels in its area to which no circumference of any of the concentric circles pass. These remain white, because none of the circles you’ve drawn ever map their circumferences to those pixels.

You can fix it by further modifying the algorithm so that it draws circles based on floating point radii instead of defining the radii in pixel space, and then draw more circles than there are pixel-radii. You could also try to increase the width of the lines drawn by those circles. If you can make them 2 px wide, they might cover those white pixels. Or you could run a filter over the portion of the image that contains the circle afterwards, and fill the gaps yourself.

The original code is seem a clever method of very quickly drawing just an outline. Using it 50 times in a row loses the “very quickly” part, so may as well go back to brute force. Scan every pixel, compute distance from the center, and paint:

for(int x=0;i<256;x++)
  for(int y=0;i<256;y++) {

    float dx = x-cx, dy=y-cy;
    float dist = Mathf.sqrt(dx*dx+dy*dy);

    if(dist<rad) SetPixel(...);
    // or  if(dx*dx+dy*dy<rad*rad)
  }

That allows you to make “thick” rings by checking between radius1 and radius2, or make ovals by scaling dx or dy. Or add some fade-out pixels with a small lerp if dist is just outside of the radius.