Extending Drawing Functions
Welcome to Custom Shapes
In this lab, you will write your own drawing functions to make shapes that MicroPython does not include by default — like circles! Let's build something amazing!
The standard SSD1306 display driver gives you rectangles, lines, and text. But it does not include a circle function. To draw a circle, you need to write one yourself.
This is a great example of how programmers extend a library to do new things.
Circle
A circle is defined by three things:
- Its center point (cx, cy) — where the middle of the circle is.
- Its radius (r) — how many pixels wide from the center to the edge.
- Its color —
1for white,0for black.
Here are the parameters for the circle function:
cx— X position of the circle center.cy— Y position of the circle center.r— the radius of the circle in pixels.color—1for on (white) and0for off (black).
Here is one way to write a circle function. It scans every pixel in a square around the circle center. If a pixel is close enough to the center, it turns the pixel on.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
What each line does:
from math import sqrt— loads the square root function.diameter = r * 2— calculates how wide the bounding square needs to be.upper_left_x = cx - r— finds the left edge of the area to scan.upper_left_y = cy - r— finds the top edge of the area to scan.for i in range(...)— loops through each column of the bounding square.for j in range(...)— loops through each row inside that column.distance = sqrt(...)— uses the Pythagorean theorem to find how far pixel (i, j) is from the center.if distance < r— checks if the pixel is inside the circle.oled.pixel(i, j, color)— turns the pixel on if it is inside the circle.
Key Idea
The math here uses the Pythagorean theorem: the distance from (i, j) to (cx, cy) is sqrt((i-cx)^2 + (j-cy)^2). If that distance is less than the radius, the pixel is inside the circle.
Testing Circle Drawing
Here is a complete program that draws circles of growing size on the screen. It uses the SPI (Serial Peripheral Interface) version of the display.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
What each section does:
WIDTH,HEIGHT— store the display size so we can use them throughout the program.Pin(2)throughPin(6)— set up the five wires that connect the SPI display.ssd1306.SSD1306_SPI(...)— creates the display object using SPI instead of I2C.draw_circle(...)— the custom function that draws a filled circle.for rad in range(1, HALF_HEIGHT + 2)— loops from radius 1 up to 34 (half of 64 + 2).oled.fill(1)— fills the screen with white before erasing circles.
Monty's Tip
You can erase a circle by drawing it again in black (color = 0). This trick works for any shape!
Drawing a Face
If you have a 128x64 display, you can use two circle calls to draw eyes. This example assumes you have written a circle() function as shown above.
1 2 3 4 | |
Try adding more circles to make a nose or a mouth!
You Can Do This!
Writing your own drawing functions takes practice. If your circle looks odd, try adjusting the if distance < r check. You are doing real computer graphics math — that is impressive!
Great Work!
You wrote a custom circle function from scratch! Next, you will learn how to measure drawing speed so you can make your programs faster.