Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing rect clipline and demo #4115

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

hankxu1212
Copy link

Resolving
Issue #3999.

Brief
On top of PR #4065, fixed syntax issues and SDL rectangle definitions.

Demo
Also attached here a demo on top of the work done in #4065.
Specifically we only ever draw the raycast once (what butlerch did earlier raises the problem of drawing x lines for each ray., where x is the number of rectangles. This was also why there were line overlaps..

Results
Shown here a results from the demo, with multiple overlapping line issues fixed.
Screenshot 2023-12-10 at 8 45 32 PM

# CLIPLINE BUG DEMO
import pygame
import numpy as np
import math
from pygame.locals import *

# Init settings
window = 800  # window size (square)
dist = 2000  # raycast max distance
angle = 2  # angle between each ray
origin = (window / 2, window / 2)  # origin of raycasts (centre of screen)
r_radii = 160  # rectangle origin radius from raycast origin
r_width = 50  # rect width
r_height = 50  # rect height
r_angle = 45  # angle of rectangles
speed = 0.02  # Speed of rectangles rotation
c = 0  # starting offset angle of rectangles

screen = pygame.display.set_mode((window, window))  # resolution
screen.fill((150, 150, 150))  # grey bg
pygame.init()  # init


# Main loop
while True:
    screen.fill((150, 150, 150))  # grey bg
    c += speed
    rects = [
        pygame.Rect(  # Init rectangle (x,y,w,h)
            np.cos(np.radians(t + c)) * r_radii + origin[0] - r_width / 2,  # x
            np.sin(np.radians(t + c)) * r_radii + origin[1] - r_height / 2,  # y
            r_width,
            r_height,
        )
        for t in range(0, 360, r_angle)
    ]  # angle iterator

    # Draw rectangles
    for r in rects:
        pygame.draw.rect(screen, "white", r)

    # Raycasts
    for theta in range(0, 360, angle):
        rad = np.radians(theta)
        point = (
            np.cos(rad) * dist + origin[0],  # x
            np.sin(rad) * dist + origin[1],  # y
        )

        # Check raycast collision
        collision = False
        res = None

        for r in rects:
            res = r.clipline(origin, point)
            if res != ():
                collision = True
                break
            
        if collision:  # check
            collision_origin, collision_dest = res
            # draws blue line from origin to collision point
            pygame.draw.line(
                screen, "blue", origin, collision_origin, 3
            )
            # draws red for the region inside the rectangle
            pygame.draw.line(
                screen, "red", collision_origin, collision_dest, 4
            )
        else:
            pygame.draw.line(
                screen, "green", origin, point, 3
            )  # draw green otherwise

    # Query quit
    pygame.display.flip()
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()

@hankxu1212 hankxu1212 changed the title Update rect.c Fixing rect clipline and demo Dec 11, 2023
@hankxu1212
Copy link
Author

@illume Request for review

@illume illume closed this May 15, 2024
@illume illume reopened this May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants