Last active
August 16, 2023 14:45
-
-
Save terrorgarten/5f36981cf747bfcdf775c267b9edfe3d to your computer and use it in GitHub Desktop.
Bresenham (midpoint) algorithm using pygame
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pygame | |
# Initialize pygame | |
pygame.init() | |
# Window dimensions and grid size | |
window_size = (800, 800) | |
grid_size = 40 | |
num_rows = window_size[1] // grid_size | |
num_cols = window_size[0] // grid_size | |
# Color constants | |
WHITE = (255, 255, 255) | |
GREEN = (0, 255, 0) | |
GRID_LINE_COLOR = (150, 150, 150) | |
# Create the window | |
window = pygame.display.set_mode(window_size) | |
pygame.display.set_caption("Bresenham algorithm demo") | |
grid = [[WHITE for _ in range(num_cols)] for _ in range(num_rows)] | |
# Function for preparation of the pygame grid | |
def draw_grid(): | |
for row in range(num_rows): | |
for col in range(num_cols): | |
# Make grid | |
pygame.draw.rect(window, grid[row][col], (col * grid_size, row * grid_size, grid_size, grid_size)) | |
# Make grid lines | |
pygame.draw.rect(window, GRID_LINE_COLOR, (col * grid_size, row * grid_size, grid_size, grid_size), 1) # Draw grid lines | |
# Function for coloring cell | |
def color_cell(x, y): | |
global grid_size | |
if x > grid_size or y > grid_size: | |
print(f"error: x={x} or y={y} our of bounds {grid_size}") | |
return | |
row = y | |
col = x | |
grid[row][col] = GREEN | |
# The bresenham algo | |
def bresenham(x1,y1,x2,y2): | |
print(f"Launching bresenham: x[{x1},{x2}], y[{y1},{y2}]") | |
dx = x2 - x1 | |
dy = y2 - y1 | |
predictor = 2 * dy - dx | |
p1 = 2 * dy | |
p2 = p1 - 2 * dx | |
y = y1 | |
x = x1 | |
print(f"----------\nSTART VALUES:\nx1 = {x1} x2 = {x2}\ny1 = {y1} y2 = {y2}\ndx = {dx} \t(x2 - x1)\ndy = {dy} \t(y2 - y1)\nP0 = {predictor} \t(2 * dy - dx)\np1 = {p1} \t(2 * dy )\np2 = {p2} \t(p1 - 2 * dx)\n----------") | |
while x <= x2: | |
print(f"[x = {x}; y = {y}] gets colored.") # every loop is identified as X because it has constant growth +1 every cycle | |
color_cell(x, y) | |
if predictor >= 0: | |
print(f"Predictor >= 0: y incremented to {y+1}. New predictor: {predictor + p2} (p0 = (p0={predictor}) + (p2={p2}))") | |
predictor += p2 | |
y += 1 | |
else: | |
print(f"Predictor < 0: y unchanged. New predictor: {predictor + p1} (p0 = (p0={predictor}) + (p1={p1}))") | |
predictor += p1 | |
x += 1 | |
# Function for purposes of getting the clicked cell | |
def get_clicked_cell(): | |
x, y = pygame.mouse.get_pos() | |
cell_x = x // grid_size # it gets a pixel in the window, transform to the cell position | |
cell_y = y // grid_size | |
return [cell_x, cell_y] | |
# Clears all cells | |
def clear_all_cells(): | |
for row in range(num_rows): | |
for col in range(num_cols): | |
grid[row][col] = WHITE | |
# Main run loop | |
def main(): | |
running = True | |
color_mode = True # Initialize with color mode on | |
while running: | |
for event in pygame.event.get(): | |
if event.type == pygame.QUIT: | |
running = False | |
elif event.type == pygame.MOUSEBUTTONDOWN: | |
if color_mode: | |
clear_all_cells() # Clear all cells if color mode is on | |
clicked_cell = get_clicked_cell() | |
print(f"Clicked cell: {clicked_cell}") | |
bresenham(0,0, clicked_cell[0], clicked_cell[1]) # Color the clicked cell | |
print("--- Done ---") | |
color_mode = not color_mode # Toggle color mode on each click | |
window.fill((10,10,10)) | |
draw_grid() | |
pygame.display.flip() | |
pygame.quit() | |
exit(0) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
installation:
1: download the file
2: pip install pygame
run:
python bresenham.py
(then just click the grid and check the ouputs for understanding the algo)