Skip to content

Conversation

@Temmie3754
Copy link
Member

This change resolves issues #1968 and pygame/pygame#3199 through a rewrite of the draw_line_width function. Drawing lines from a to b should now also be the same as drawing from b to a.

@Temmie3754 Temmie3754 requested a review from a team as a code owner March 7, 2023 10:23
Copy link
Member

@MightyJosip MightyJosip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is good now. If you would like to do it, can you also add the tests for this

@Starbuck5 Starbuck5 added the draw pygame.draw label Mar 10, 2023
Copy link
Member

@MyreMylar MyreMylar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Fixes the original issue that was visible in this test program:

import pygame


WIDTH, HEIGHT = 800, 600
FPS = 60

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

test_surf = pygame.Surface((100, 100))
test_surf.fill((255, 255, 255))

rect = pygame.Rect(0, 0, 100, 100)

test_surf_pos = (150, 150)

running = True
while running:
    clock.tick(FPS)
    screen.fill("black")

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

    test_surf.fill("white")
    rect.center = pygame.mouse.get_pos()[0] - test_surf_pos[0], pygame.mouse.get_pos()[1] - test_surf_pos[0]
    pygame.draw.rect(test_surf, "red", rect, 30, 0, 0, 20, 0, 20)
    screen.blit(test_surf, test_surf_pos)

    pygame.display.flip()

Try moving the D shape around inside the white surface with the mouse. On main you get lots of artefacts when parts of the D are clipped off screen and parts, which should still be visible get culled. After this PR everything looks as it should.

@itzpr3d4t0r
Copy link
Member

itzpr3d4t0r commented Mar 12, 2023

I tested this and confirm to be faster with this PR:

OLD:
0.3472604100001263
0.34475235999998405
0.3701231299995925
0.33968151999979457
0.3420160299998315
0.34054873000004593
0.3426739000000453
0.3402624100001049
0.35369226999973763
0.34050359000011665

NEW
0.23466548999986117
0.2332005099999151
0.23741479000018445
0.23511996999986878
0.23276994999960152
0.23450463999997737
0.2321502300004795
0.23337097000003268
0.23315945000049396
0.2355904100000771

OLD Mean: 0.34615143499993795
NEW Mean: 0.23419464100004916
Uplift: 47.81%

Code:

from random import randint

import pygame
from pygame.draw import line as draw_line
from timeit import repeat
from statistics import mean

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


def rand_color():
    return randint(0, 255), randint(0, 255), randint(0, 255)


def create_lines(number, width):
    return [(rand_color(),
             (randint(0, WIDTH), randint(0, HEIGHT)),
             (randint(0, WIDTH), randint(0, HEIGHT)), width)
            for _ in range(number)]


lst = create_lines(100, 3)

for _ in range(10):
    print(mean(repeat("for line in lst: draw_line(win, *line)", globals=globals(), number=1000, repeat=10)))

@itzpr3d4t0r itzpr3d4t0r added this to the 2.2 milestone Mar 15, 2023
@MyreMylar MyreMylar merged commit 4fc37dd into pygame-community:main Mar 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

draw pygame.draw

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants