Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 23218

distance of a point from the lines that are contained in a list

$
0
0

I am making a python animation for a project in which, I am taking a star shaped boundary in which there are two balls which are moving inside that star. If the balls collide to other balls, a new ball is formed. The star boundary is working as wall of room , that if ball touches it , gets bounced off (according to the angles of reflections) the problem I am facing is how would i define the bouncing function , I have made the star using line segments and all those line segments are stored in a list. I want to define it like, if the distance between the any of the line segments from the list and the ball is less than the ball's radius then it gets bounced off. The problem is, if I define that function then it is taking complete equation of the line and the straight lines that are the borders of the star (if extended) also passes through inside the star and the ball is getting bounced off from those invisible lines. How can I define that function that it works only for line segments not for the extended lines. I did this animation for a circle , it is easy to handle it with a circle because there is only one line "the circumference of that circle" to define functions for. Here is a working code for circle. You don't need to go through whole code , it is just for the idea for how I am doing it.

import pygameimport sysimport mathimport random# Initialize Pygamepygame.init()# Set up the windowwidth, height = 600, 600window = pygame.display.set_mode((width, height))pygame.display.set_caption("Bouncing Balls Inside a Circle")# ColorsBLACK = (0, 0, 0)WHITE = (255, 255, 255)colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (0, 255, 255)]# Circle parameterscircle_center = (width // 2, height // 2)circle_radius = 200circle_thickness = 3# Ball parametersball_radius = 10balls = []# Function to create a new ball with a random colordef create_ball():    angle = random.uniform(0, 2 * math.pi)    distance = random.uniform(0, circle_radius - ball_radius)    x = circle_center[0] + distance * math.cos(angle)    y = circle_center[1] + distance * math.sin(angle)    speed = [random.choice([-.25, .25]), random.choice([-.25, .25])]  # Random initial speed    color = random.choice(colors)    return {"pos": [x, y], "speed": speed, "color": color}# Function to check collision between ballsdef check_collision(ball1, ball2):    dist = math.sqrt((ball1["pos"][0] - ball2["pos"][0]) ** 2 + (ball1["pos"][1] - ball2["pos"][1]) ** 2)    return dist <= 2 * ball_radius# Function to handle collision and ball bouncingdef handle_collision(ball1, ball2):    dx = ball2["pos"][0] - ball1["pos"][0]    dy = ball2["pos"][1] - ball1["pos"][1]    distance = math.sqrt(dx ** 2 + dy ** 2)    overlap = 2 * ball_radius - distance    normal_x = dx / distance    normal_y = dy / distance    correction = [overlap * normal_x, overlap * normal_y]    ball1["pos"][0] -= correction[0]    ball1["pos"][1] -= correction[1]    ball2["pos"][0] += correction[0]    ball2["pos"][1] += correction[1]    # Calculate reflection angles    dot_product1 = ball1["speed"][0] * normal_x + ball1["speed"][1] * normal_y    dot_product2 = ball2["speed"][0] * normal_x + ball2["speed"][1] * normal_y    reflect_x1 = ball1["speed"][0] - 2 * dot_product1 * normal_x    reflect_y1 = ball1["speed"][1] - 2 * dot_product1 * normal_y    reflect_x2 = ball2["speed"][0] - 2 * dot_product2 * normal_x    reflect_y2 = ball2["speed"][1] - 2 * dot_product2 * normal_y    ball1["speed"] = [reflect_x1, reflect_y1]    ball2["speed"] = [reflect_x2, reflect_y2]# Function to add a new ball to the circledef add_new_ball():    if len(balls) > 0:        balls.append(create_ball())# Add two initial ballsballs.append(create_ball())balls.append(create_ball())# Main loopwhile True:    window.fill(BLACK)    # Check for events    for event in pygame.event.get():        if event.type == pygame.QUIT:            pygame.quit()            sys.exit()    # Update ball positions    for ball in balls:        ball["pos"][0] += ball["speed"][0]        ball["pos"][1] += ball["speed"][1]    # Check if any two balls collide    for i in range(len(balls)):        for j in range(i + 1, len(balls)):            if check_collision(balls[i], balls[j]):                handle_collision(balls[i], balls[j])                add_new_ball()  # Add a new ball if collision occurs    # Check if the balls hit the walls of the circle    for ball in balls:        distance_to_center = math.sqrt((ball["pos"][0] - circle_center[0]) ** 2 + (ball["pos"][1] - circle_center[1]) ** 2)        if distance_to_center + ball_radius >= circle_radius:            # Calculate reflection angle            dx, dy = ball["speed"]            normal_x = ball["pos"][0] - circle_center[0]            normal_y = ball["pos"][1] - circle_center[1]            mag_normal = math.sqrt(normal_x ** 2 + normal_y ** 2)            normal_x /= mag_normal            normal_y /= mag_normal            dot_product = dx * normal_x + dy * normal_y            reflect_x = dx - 2 * dot_product * normal_x            reflect_y = dy - 2 * dot_product * normal_y            ball["speed"][0] = reflect_x            ball["speed"][1] = reflect_y    # Draw the circle    pygame.draw.circle(window, WHITE, circle_center, circle_radius, circle_thickness)    # Draw the balls    for ball in balls:        pygame.draw.circle(window, ball["color"], (int(ball["pos"][0]), int(ball["pos"][1])), ball_radius)    pygame.display.flip()

I just want to replace the circular boundary with a star shaped boundary. Any help is appreciated.Thank You.


Viewing all articles
Browse latest Browse all 23218

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>