firefly
firefly

Reputation: 312

Pygame doesn't draw rectangles on the screen after a specific threshold

I'm trying to make a visualisation for various sorting algorithms and I was playing around with Pygame to try and draw the rectangles that I need.

In the below code, the user is given multiples inputs: the lowest value of the list to be sorted, the highest value, and the number of elements the list is going to have. The elements are going to be randomly generated.

Then I'm getting the user's screen size so that I can have an appropriate window for the visualisation. Based on the visualisation window and the user's input, I'm setting up the width and height of the rectangles, so that each rectangle has the same width and that they are scaled based on the highest value.

Almost everything is nice and fine with this approach, but there's one thing that I can't figure out. It seems that setting the number of elements (n, in the code below) too high, the rectangles are not being drawn.

My asumption is that after a specific threshold, RECT_W, which is the width of the rectangles, becomes to small for Pygame to draw it.

What options do I have to solve it, except of having the number of elements smaller than a specific value?

import random
import pygame
import color_constants as colors
import ctypes
import copy
from pygame.locals import *


# Read data based on user's input
def readData():
    listOfNumbers = []
    data = dict()

    print("Lowest Value: ")
    numLow = int(input())

    print("Highest Value: ")
    numHigh = int(input())

    print("Length of list: ")
    n = int(input())

    for i in range(0, n):
        listOfNumbers.append(random.randint(numLow, numHigh))

    origLst = copy.copy(listOfNumbers)
    data.update({'lst': origLst})
    data.update({'numLow': numLow})
    data.update({'numHigh': numHigh})
    data.update({'n': n})
    data.update({'sorted': listOfNumbers})

    return data

if __name__ == "__main__":
    data = readData()

    # Getting the user's screen size
    user32 = ctypes.windll.user32
    SCREENSIZE = user32.GetSystemMetrics(0)-100, user32.GetSystemMetrics(1)-100
    SCREEN_W = SCREENSIZE[0]
    SCREEN_H = SCREENSIZE[1]

    # Setting and scaling the size of rectangle based on the number of elements (n)
    # and the highest number (numHigh)
    RECT_W = SCREEN_W // data['n']
    RECT_H = SCREEN_H / (data['numHigh'])

    # Setting up the color literals
    RED = (255, 255, 255)
    GRAY = (0, 0, 0)

    pygame.init()
    screen = pygame.display.set_mode(SCREENSIZE)

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

        for i in range(data['n']):
            rect = Rect(i*RECT_W, 0, RECT_W, RECT_H * data['lst'][i])
            rect.bottom = SCREEN_H
            pygame.draw.rect(screen, RED, rect)
        pygame.display.flip()

Upvotes: 1

Views: 193

Answers (1)

Rabbid76
Rabbid76

Reputation: 211278

If data['n'] is greater than SCREEN_W, RECT_W is 0. A coordinate is truncated when drawing. You cannot draw a fraction of a pixel. The size of the rectangle can only be integral (0, 1, 2 ...). Hence, you cannot draw a rectangle with a size less than 1.
You can draw the rectangles on a large surface and scale down the surface. However, the rectangles get blurred. So, this is no good option.

Upvotes: 1

Related Questions