Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to subtract geometry in pygame?

I am trying to make a logic in which i can subtract the geometrical shapes. Lets say i have to subtract a circle from a rectangle.

The idea is to draw each point of the rectangle as a single individual point using win.set_at(). And then when we need to subtract the circle from the rectangle we an simply calculate that the point on which we are drawing and completing our square lies or not in the circle. If it lies then don’t set pixels else draw the pixel. This is my code:


import pygame

WIDTH, HEIGHT = 700, 500

win = pygame.display.set_mode((WIDTH, HEIGHT))

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)

def drawer(window, x, y, radius, s_l, s_w, s_x, s_y):
    for i in range(0, HEIGHT):
        for j in range(0, WIDTH):
            distance = (x - j)**2 + (y - i)**2
            if not distance <= radius**2 and i >= s_y and j >= s_x and i <= s_w + s_x and j <= s_l + s_y:
                window.set_at((j, i), BLACK)
    
c_x, c_y = 130, 150
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        
    win.fill(WHITE)
    drawer(win, c_x, c_y, 30, 100, 100, 100, 100)
    pygame.display.flip()

pygame.quit()

But is it is quite slow. Can you suggest a better way (more optimized algorithm) of doing it.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

For a good performance I suggest to use pygame.mask. Draw the shapes on pygame.Surface objects and create masks from the surfaces:

mask1 = pygame.mask.from_surface(shape1)
mask2 = pygame.mask.from_surface(shape2)

Invert the mask of the second shape and create the overlapping mask. Finally, create a new _Surface: from the overlapping mask:

mask2.invert()
subtract_maks = mask1.overlap_mask(mask2, (0, 0))
subtract_shape = subtract_maks.to_surface(setcolor = "red", unsetcolor=(0, 0, 0, 0))

Minimal example

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

shape1 = pygame.Surface((200, 200), pygame.SRCALPHA)
pygame.draw.circle(shape1, "white", (100, 100), 100)
shape2 = pygame.Surface((200, 200), pygame.SRCALPHA)
pygame.draw.rect(shape2, "white", (25, 50, 150, 100))

mask1 = pygame.mask.from_surface(shape1)
mask2 = pygame.mask.from_surface(shape2)

mask2.invert()
subtract_maks = mask1.overlap_mask(mask2, (0, 0))
subtract_shape = subtract_maks.to_surface(setcolor = "red", unsetcolor=(0, 0, 0, 0))

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            print(pygame.key.name(event.key))
 
    window.fill("gray")
    window.blit(subtract_shape, (50, 50))
    pygame.display.flip()

pygame.quit()
exit()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading