4

I'm trying to draw a pixelated (blocky) circle in TikZ where each filled 1×1 square corresponds exactly to an integer grid cell (think Minecraft blocks). Given a center and radius, I want a compact TikZ/PGF macro or clear algorithm that selects which unit squares to fill so the rasterized shape matches a standard discrete circle (midpoint/Bresenham or distance-threshold) while preserving octant symmetry and avoiding visual gaps or doubled squares on diagonals.

What is a simple, robust method to compute the set of grid cells for a given (integer or real) radius, and how can that be implemented cleanly in TikZ? Short macro examples, notes on rounding/aliasing pitfalls, and advice on scaling to a fixed cell size would be especially useful. For a quick visual reference I compared expected output with a pixel-circle preview online (pixel-circle preview).

New contributor
Jax is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
6

1 Answer 1

4

While you are waiting for TikZ-help, here is an effort in Metapost for comparison.

enter image description here

You need to compile this with lualatex:

\documentclass[border=5mm]{standalone}
\usepackage{luamplib}
\begin{document}
\mplibtextextlabel{enable}
\begin{mplibcode}
vardef block_circle(expr r, s) = image(
  save block, b, n, w; 
  path block; block = unitsquare shifted -(.5,.5) scaled s;
  numeric n; n = round(r/s) + 1;
  for x = -n upto n:
    for y = -n upto n:
      pair w; w = (x,y) scaled s;
      if abs w < r:
        path b; b = block scaled 0.9 rotated 3/4 normaldeviate shifted w;
        if xpart (fullcircle scaled 2r intersectiontimes b) < 0:
          fill b withcolor (uniformdeviate 1, uniformdeviate 3/4, uniformdeviate 1/2);
        fi
        draw b if n > 10: withpen pencircle scaled 1/4 fi;
      fi
    endfor
  endfor
) enddef;

beginfig(1);
  for i = 1 upto 4:
    draw block_circle(64, 5i) shifted (144i, 0);
    draw fullcircle scaled 128 shifted (144i, 0) withcolor red;
  endfor
endfig;
\end{mplibcode}
\end{document}

There are a couple of things to adapt / fiddle with:

  • You might not want the fancy decoration on each square, so you could change the path b; line to

      path b; b = block shifted w;
    
  • You might want to include squares that touch the circle; if so you can get rid of the inner if so that it does not bother with the intersection check.

  • You might want to exclude squares that touch the circle; if so you should move the draw b line inside the inner if.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.