pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
766 stars 120 forks source link

Allow degenerate circles (radius = 0) #2913

Closed damusss closed 4 days ago

damusss commented 3 weeks ago

note: I've modified the circle init error message to include the radius, as it was very unclear before. If you don't want degenerate circles, this modification should still be added IMHO, so let me know.

I've slightly modified the code, the tests and the docs to allow degenerate circles to exist. I've run through every line where the radius attribute is used and I checked for divisions with the radius but they were not present. Why?

Tell me if you'd like more tests or if I missed something. Of course you can not agree with allowing degenerate circles, I made this pull request so that if you think they should be there, you'll find a PR ready for it.

oddbookworm commented 3 weeks ago

I'm requesting a review from @itzpr3d4t0r as the resident pygame-geometry expert

oddbookworm commented 3 weeks ago

I tested this locally with this test script, and it seems to work exactly as I was expecting it to

import pygame
import pygame.geometry

screen = pygame.display.set_mode((50, 50), pygame.SCALED)
stationary_circle = pygame.geometry.Circle(*screen.get_rect().center, 0)

radius = 10
moving_circle = pygame.geometry.Circle(screen.get_rect().center, radius)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.MOUSEWHEEL:
            radius = radius + event.y
            if radius < 0:
                radius = 0

    pos = pygame.mouse.get_pos()
    moving_circle.center = pos
    moving_circle.radius = radius

    color = "green"
    if moving_circle.collidecircle(stationary_circle):
        color = "red"

    screen.fill("black")
    screen.set_at(stationary_circle.center, "blue")
    if radius:
        pygame.draw.aacircle(screen, color, moving_circle.center, moving_circle.radius, 1)
    else:
        screen.set_at(moving_circle.center, color)
    pygame.display.flip()