Collecting my attempts to improve at tech, art, and life

Circular Grids With Python and Pillow

Tags: python programming

A while back, I wrote about drawing grids with Python and Pillow. I no longer use that code so much, since Procreate now includes square grids in its drawing aid tools.

One idea sitting in my Taskwarrior queue for a full year now would still be useful, though. A circle template could help me break out of the square grid with my Celtic and Tangle drawings.

I already create circular drawings using symmetry tools in my drawing apps. Those are doodles, though: unplanned and improvised. I sketch and see what the automated symmetry produces from my linework. Circle templates simplify planning a complex image which I then produce, probably without using symmetry tools.

So, let’s write a little code!

I’ll keep using Python, since that worked for me last time. Lately I have been using the Anaconda Distribution for my Python programming needs. It includes a number of Python packages, including Pillow!

My template includes three characteristics:

• an origin in the center of my square image
• some concentric circles increasing in radius by a fixed amount
• some line segments slicing the image from the origin point to the outermost circle

Write some code

I will save myself effort by grabbing some of the work used for drawing grids and putting into a new class.

My CircleTemplate class knows how to construct, save, and show a blank image. argparse processes the command line arguments for image size, number of circles, and number of slices. I added defaults so I don’t have to type in a value every time I tested the script for this post.

I can build on this framework. Time to fill in the blanks.

Draw some circles

I need to figure out my origin, the center for my circles and slices. Since the image is a square, it will be the same along both the X and Y axes. This means I only need to calculate a single midpoint.

Each time we move on to a new radius, ImageDraw.arc creates a circle by drawing a 360 degree arc within bounding_box, a square that extends radius pixels from a midpoint along the x and y axes.

Right. I could do some moderately clever math to calculate angles and draw lines from the midpoint, or I could use the existing ImageDraw.pieslice method to accomplish pretty much the same thing. If you read the section title, you can probably guess what I chose.

I’m dividing the 360 degrees of a circle into slice_count pieces. ImageDraw.pieslice draws a tidy wedge at the angles we give it fitting the bounding box defined by my largest circle.

How does that look?

It looks pretty cool.

I need more circles and slices for the drawings I’m thinking of, though. Many more.

Yes, that’s more like it.

This is all I need for a drawing template. Using transformation tools and the right blending modes, I can maneuver and manipulate my grid however I need for a drawing template!

I’ll stop here so I can get to my drawing.

Added to vault 2024-01-15. Updated on 2024-02-01