# PicoGraphics, creating shapes with Alpha

Hey folks!

I am trying to draw a hollow circle with a thickness. I am using the approach of drawing a large circle with one color and then a smaller one with the BG Color. This approach allows me to get the hollow circle. But if I were to move this shape over anything else, then the BG will overlap.

Any smart people here that can figure out a way to substract shapes, and keep whatever is in the background open?

I was thinking of uploading a PNG, but I don’t know how to nominate a color to be the alpha.

Thanks!

I’m taking along to see if anybody comes up with a solution. As this sounds really interesting and might be something I’d try to do at some point.

I draw a circle in a circle and use it as a moving marker. I’m purposely covering up the background though.

Sounds like we need a draw_ring function with a thickness option. Like the draw_line.

EDIT: There is a flurry of activity going on Pico Graphics wise, Fonts and Pico Vector.
Workflow runs · pimoroni/pimoroni-pico (github.com)

Might be a good idea to post this as an issue on Github.
It will be better seen by those that do all the hard work coding wise.
Issues · pimoroni/pimoroni-pico (github.com)

This is the method I use in my graphics system:

``````def clear(c):
LCD.fill(colour(0,150,0)) # Green

def ring(x,y,r,c):
LCD.pixel(x-r,y,c)
LCD.pixel(x+r,y,c)
LCD.pixel(x,y-r,c)
LCD.pixel(x,y+r,c)
for i in range(1,r):
a = int(math.sqrt(r*r-i*i)) # Pythagoras - so useful!
LCD.pixel(x-a,y-i,c)
LCD.pixel(x+a,y-i,c)
LCD.pixel(x-a,y+i,c)
LCD.pixel(x+a,y+i,c)
LCD.pixel(x-i,y-a,c)
LCD.pixel(x+i,y-a,c)
LCD.pixel(x-i,y+a,c)
LCD.pixel(x+i,y+a,c)
# Fill in the missed pixels !
a = int(math.sqrt(r*r-i*i)+.6) # small offset outwards
LCD.pixel(x-a,y-i,c)
LCD.pixel(x+a,y-i,c)
LCD.pixel(x-a,y+i,c)
LCD.pixel(x+a,y+i,c)
LCD.pixel(x-i,y-a,c)
LCD.pixel(x+i,y-a,c)
LCD.pixel(x-i,y+a,c)
LCD.pixel(x+i,y+a,c)

def thick_ring(x,y,R,r,c):
for ii in range(r,R):
ring(x,y,ii,c)

clear(0)

thick_ring(120,120,100,90,colour(255,255,0))
ring(120,120,95,colour(0,0,255))
LCD.show()
``````

You may need to change the format of the pixel instructions to your system. It works but is not terribly fast - so many calculations.

This is an alternative method. It draws vertical lines between the outer and inner radii.

``````def thick_ring2(cx,cy,r,t,c):
R = int(r+t/2)
r = int(r-t/2)
print(R,r)
for i in range(0,R):
t = int(math.sqrt(R*R-i*i))
if i <= r:
b = int(math.sqrt(r*r-i*i))
LCD.line(cx+i,cy-t,cx+i,cy-b,c)
LCD.line(cx-i,cy-t,cx-i,cy-b,c)
LCD.line(cx-i,cy+t,cx-i,cy+b,c)
LCD.line(cx+i,cy+t,cx+i,cy+b,c)
else:
LCD.line(cx+i,cy-t,cx+i,cy,c)
LCD.line(cx-i,cy-t,cx-i,cy,c)
LCD.line(cx-i,cy+t,cx-i,cy,c)
LCD.line(cx+i,cy+t,cx+i,cy,c)
LCD.show()
``````

This works pretty quickly. There will always be a great deal of calculations with rings. Using vline() might make it a bit quicker.

Quick video to show the speed here:

1 Like

You can draw a hollow circle with the new PicoVector stuff like this:

``````from picographics import PicoGraphics, DISPLAY_TUFTY_2040
from picovector import PicoVector, RegularPolygon, ANTIALIAS_NONE, ANTIALIAS_X4, ANTIALIAS_X16

display = PicoGraphics(DISPLAY_TUFTY_2040)

vector = PicoVector(display)
vector.set_antialiasing(ANTIALIAS_X4)

BLACK = display.create_pen(0, 0, 0)
WHITE = display.create_pen(255, 255, 255)

WIDTH, HEIGHT = display.get_bounds()

inner_circle = RegularPolygon(int(WIDTH / 2), int(HEIGHT / 2), 48, HEIGHT / 2 - 8)
outer_circle = RegularPolygon(int(WIDTH / 2), int(HEIGHT / 2), 48, HEIGHT / 2)

display.set_pen(BLACK)
display.clear()
display.set_pen(WHITE)

vector.draw(outer_circle, inner_circle)
display.update()
``````

It’s slow though!