Spaces:
Runtime error
Runtime error
Commit
·
a56f8f7
1
Parent(s):
4ae264c
add bouncing ball simulation in a spinning hexagon with collision detection
Browse files
examples/bouncing_ball_hexagon/flavioAd_R1.py
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
https://x.com/flavioAd/status/1885449107436679394
|
| 3 |
+
https://codeishot.com/6yxHiwZ2
|
| 4 |
+
changed colors for visualization
|
| 5 |
+
tried to match params to o3 results
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
import pygame
|
| 9 |
+
import numpy as np
|
| 10 |
+
import math
|
| 11 |
+
|
| 12 |
+
# Initialize Pygame
|
| 13 |
+
pygame.init()
|
| 14 |
+
WIDTH, HEIGHT = 800, 600
|
| 15 |
+
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
| 16 |
+
clock = pygame.time.Clock()
|
| 17 |
+
FPS = 100 # Match with physics time step
|
| 18 |
+
|
| 19 |
+
# Simulation parameters
|
| 20 |
+
SCALE = 40 # pixels per simulation unit
|
| 21 |
+
radius_hexagon = 5.0
|
| 22 |
+
ball_radius = 0.2
|
| 23 |
+
angular_velocity = np.pi / 6 # rad/s
|
| 24 |
+
gravity = 9.81 # m/s²
|
| 25 |
+
coefficient_of_restitution = 0.9
|
| 26 |
+
friction_coefficient = 0.2
|
| 27 |
+
dt = 1.0 / FPS # Time step matches frame rate
|
| 28 |
+
|
| 29 |
+
# Initialize ball state
|
| 30 |
+
ball_pos = np.array([0.0, 3.0])
|
| 31 |
+
ball_vel = np.array([3.0, 0.0])
|
| 32 |
+
|
| 33 |
+
# Create hexagon vertices (unrotated)
|
| 34 |
+
angles = np.linspace(0, 2*np.pi, 7)[:-1]
|
| 35 |
+
original_vertices = radius_hexagon * np.column_stack([np.cos(angles), np.sin(angles)])
|
| 36 |
+
current_angle = 0.0
|
| 37 |
+
|
| 38 |
+
def get_rotated_vertices(angle):
|
| 39 |
+
"""Return vertices rotated by given angle"""
|
| 40 |
+
rot_mat = np.array([[np.cos(angle), -np.sin(angle)],
|
| 41 |
+
[np.sin(angle), np.cos(angle)]])
|
| 42 |
+
return original_vertices @ rot_mat
|
| 43 |
+
|
| 44 |
+
def screen_pos(pos):
|
| 45 |
+
"""Convert simulation coordinates to Pygame screen coordinates"""
|
| 46 |
+
return (WIDTH//2 + int(pos[0] * SCALE),
|
| 47 |
+
HEIGHT//2 - int(pos[1] * SCALE))
|
| 48 |
+
|
| 49 |
+
# Colors
|
| 50 |
+
BG_COLOR = (0, 0, 0)
|
| 51 |
+
HEX_COLOR = (255, 255, 255)
|
| 52 |
+
BALL_COLOR = (255, 0, 0)
|
| 53 |
+
|
| 54 |
+
running = True
|
| 55 |
+
while running:
|
| 56 |
+
# Handle events
|
| 57 |
+
for event in pygame.event.get():
|
| 58 |
+
if event.type == pygame.QUIT:
|
| 59 |
+
running = False
|
| 60 |
+
|
| 61 |
+
# Update hexagon rotation
|
| 62 |
+
current_angle += angular_velocity * dt
|
| 63 |
+
if current_angle > 2*np.pi:
|
| 64 |
+
current_angle -= 2*np.pi
|
| 65 |
+
r_vertices = get_rotated_vertices(current_angle)
|
| 66 |
+
|
| 67 |
+
# Apply gravity
|
| 68 |
+
ball_vel[1] -= gravity * dt # Gravity acts downward in simulation
|
| 69 |
+
|
| 70 |
+
# Save previous position and update ball
|
| 71 |
+
prev_pos = np.copy(ball_pos)
|
| 72 |
+
ball_pos += ball_vel * dt
|
| 73 |
+
|
| 74 |
+
# Collision detection and response
|
| 75 |
+
collision_occurred = False
|
| 76 |
+
for i in range(len(r_vertices)):
|
| 77 |
+
A = r_vertices[i]
|
| 78 |
+
B = r_vertices[(i+1)%len(r_vertices)]
|
| 79 |
+
|
| 80 |
+
edge_vec = B - A
|
| 81 |
+
normal = np.array([-edge_vec[1], edge_vec[0]])
|
| 82 |
+
normal /= np.linalg.norm(normal)
|
| 83 |
+
|
| 84 |
+
# Find closest point on edge
|
| 85 |
+
AB = B - A
|
| 86 |
+
AP = prev_pos - A
|
| 87 |
+
t = np.dot(AP, AB) / np.dot(AB, AB)
|
| 88 |
+
t = np.clip(t, 0.0, 1.0)
|
| 89 |
+
closest_point = A + t * AB
|
| 90 |
+
|
| 91 |
+
# Check collision
|
| 92 |
+
dist_vec = prev_pos - closest_point
|
| 93 |
+
distance = np.linalg.norm(dist_vec)
|
| 94 |
+
|
| 95 |
+
if distance < ball_radius:
|
| 96 |
+
# Calculate wall velocity at collision point
|
| 97 |
+
wall_vel = angular_velocity * np.array([-closest_point[1], closest_point[0]])
|
| 98 |
+
|
| 99 |
+
# Calculate relative velocity
|
| 100 |
+
rel_vel = ball_vel - wall_vel
|
| 101 |
+
normal_vel = np.dot(rel_vel, normal) * normal
|
| 102 |
+
tangent_vel = rel_vel - normal_vel
|
| 103 |
+
|
| 104 |
+
# Apply collision response
|
| 105 |
+
new_normal_vel = -coefficient_of_restitution * normal_vel
|
| 106 |
+
new_tangent_vel = (1 - friction_coefficient) * tangent_vel
|
| 107 |
+
new_rel_vel = new_normal_vel + new_tangent_vel
|
| 108 |
+
|
| 109 |
+
# Update ball velocity
|
| 110 |
+
ball_vel = wall_vel + new_rel_vel
|
| 111 |
+
|
| 112 |
+
# Position correction
|
| 113 |
+
penetration = ball_radius - distance
|
| 114 |
+
ball_pos = prev_pos + penetration * normal
|
| 115 |
+
|
| 116 |
+
collision_occurred = True
|
| 117 |
+
break
|
| 118 |
+
|
| 119 |
+
# Draw everything
|
| 120 |
+
screen.fill(BG_COLOR)
|
| 121 |
+
|
| 122 |
+
# Draw hexagon
|
| 123 |
+
hex_points = [screen_pos(v) for v in r_vertices]
|
| 124 |
+
pygame.draw.polygon(screen, HEX_COLOR, hex_points, 3)
|
| 125 |
+
|
| 126 |
+
# Draw ball
|
| 127 |
+
ball_scr_pos = screen_pos(ball_pos)
|
| 128 |
+
pygame.draw.circle(screen, BALL_COLOR, ball_scr_pos, int(ball_radius * SCALE))
|
| 129 |
+
|
| 130 |
+
pygame.display.flip()
|
| 131 |
+
clock.tick(FPS)
|
| 132 |
+
|
| 133 |
+
pygame.quit()
|
examples/bouncing_ball_hexagon/flavioAd_o3mini.py
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
https://x.com/flavioAd/status/1885449107436679394
|
| 3 |
+
https://codeishot.com/6yxHiwZ2
|
| 4 |
+
https://codeishot.com/1SlxNjbP
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
import math
|
| 8 |
+
import numpy as np
|
| 9 |
+
import pygame
|
| 10 |
+
|
| 11 |
+
# -----------------------------
|
| 12 |
+
# Helper functions
|
| 13 |
+
# -----------------------------
|
| 14 |
+
def rotate_point(point, angle, center):
|
| 15 |
+
"""
|
| 16 |
+
Rotate a 2D point around a given center by 'angle' radians.
|
| 17 |
+
"""
|
| 18 |
+
s, c = math.sin(angle), math.cos(angle)
|
| 19 |
+
translated = point - center
|
| 20 |
+
rotated = np.array([translated[0]*c - translated[1]*s,
|
| 21 |
+
translated[0]*s + translated[1]*c])
|
| 22 |
+
return rotated + center
|
| 23 |
+
|
| 24 |
+
def closest_point_on_segment(A, B, P):
|
| 25 |
+
"""
|
| 26 |
+
Returns the closest point on the line segment AB to point P.
|
| 27 |
+
"""
|
| 28 |
+
AB = B - A
|
| 29 |
+
if np.allclose(AB, 0):
|
| 30 |
+
return A
|
| 31 |
+
t = np.dot(P - A, AB) / np.dot(AB, AB)
|
| 32 |
+
t = np.clip(t, 0, 1)
|
| 33 |
+
return A + t * AB
|
| 34 |
+
|
| 35 |
+
def compute_inward_normal(A, B, poly_center):
|
| 36 |
+
"""
|
| 37 |
+
Compute the inward normal (unit vector) for edge AB of a polygon,
|
| 38 |
+
ensuring that the normal points from the edge toward the polygon’s center.
|
| 39 |
+
"""
|
| 40 |
+
# Compute candidate normal: rotate edge vector by 90 degrees
|
| 41 |
+
edge = B - A
|
| 42 |
+
candidate = np.array([edge[1], -edge[0]])
|
| 43 |
+
candidate_norm = candidate / np.linalg.norm(candidate)
|
| 44 |
+
# Ensure it points toward the polygon center.
|
| 45 |
+
mid = (A + B) / 2.0
|
| 46 |
+
if np.dot(poly_center - mid, candidate_norm) < 0:
|
| 47 |
+
candidate_norm = -candidate_norm
|
| 48 |
+
return candidate_norm
|
| 49 |
+
|
| 50 |
+
# -----------------------------
|
| 51 |
+
# Main simulation
|
| 52 |
+
# -----------------------------
|
| 53 |
+
def main():
|
| 54 |
+
# Initialize Pygame
|
| 55 |
+
pygame.init()
|
| 56 |
+
WIDTH, HEIGHT = 800, 600
|
| 57 |
+
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
| 58 |
+
pygame.display.set_caption("Ball in a Rotating Hexagon")
|
| 59 |
+
clock = pygame.time.Clock()
|
| 60 |
+
running = True
|
| 61 |
+
|
| 62 |
+
# -----------------------------
|
| 63 |
+
# Simulation parameters
|
| 64 |
+
# -----------------------------
|
| 65 |
+
# Physics constants
|
| 66 |
+
gravity = np.array([0, 500.0]) # pixels/s^2 (downward)
|
| 67 |
+
restitution = 0.9 # bounce factor (0 < restitution <= 1)
|
| 68 |
+
friction_coef = 0.2 # friction coefficient for tangential velocity
|
| 69 |
+
|
| 70 |
+
# Ball properties
|
| 71 |
+
ball_radius = 15
|
| 72 |
+
ball_position = np.array([WIDTH/2, HEIGHT/2])
|
| 73 |
+
ball_velocity = np.array([200.0, -150.0]) # initial velocity in pixels/s
|
| 74 |
+
|
| 75 |
+
# Hexagon properties
|
| 76 |
+
hex_center = np.array([WIDTH/2, HEIGHT/2])
|
| 77 |
+
hex_radius = 200 # distance from center to vertex
|
| 78 |
+
hexagon_local = [] # vertices in local (non-rotated) coordinates
|
| 79 |
+
num_sides = 6
|
| 80 |
+
for i in range(num_sides):
|
| 81 |
+
angle = 2 * math.pi * i / num_sides
|
| 82 |
+
vertex = np.array([hex_radius * math.cos(angle),
|
| 83 |
+
hex_radius * math.sin(angle)])
|
| 84 |
+
hexagon_local.append(vertex)
|
| 85 |
+
hexagon_local = np.array(hexagon_local)
|
| 86 |
+
|
| 87 |
+
hex_angle = 0.0 # initial rotation angle in radians
|
| 88 |
+
hex_angular_velocity = math.radians(30) # constant angular velocity (30°/s)
|
| 89 |
+
|
| 90 |
+
# -----------------------------
|
| 91 |
+
# Main loop
|
| 92 |
+
# -----------------------------
|
| 93 |
+
while running:
|
| 94 |
+
dt = clock.tick(60) / 1000.0 # seconds elapsed since last frame (aim for 60 FPS)
|
| 95 |
+
|
| 96 |
+
# --- Event Handling ---
|
| 97 |
+
for event in pygame.event.get():
|
| 98 |
+
if event.type == pygame.QUIT:
|
| 99 |
+
running = False
|
| 100 |
+
|
| 101 |
+
# --- Update Hexagon ---
|
| 102 |
+
hex_angle += hex_angular_velocity * dt
|
| 103 |
+
|
| 104 |
+
# Compute the global (rotated) positions of the hexagon vertices.
|
| 105 |
+
hexagon_global = []
|
| 106 |
+
for vertex in hexagon_local:
|
| 107 |
+
# Since the local vertices are relative to hex_center, we can
|
| 108 |
+
# rotate them directly and then add hex_center.
|
| 109 |
+
s, c = math.sin(hex_angle), math.cos(hex_angle)
|
| 110 |
+
rotated = np.array([vertex[0]*c - vertex[1]*s,
|
| 111 |
+
vertex[0]*s + vertex[1]*c])
|
| 112 |
+
hexagon_global.append(rotated + hex_center)
|
| 113 |
+
hexagon_global = np.array(hexagon_global)
|
| 114 |
+
|
| 115 |
+
# --- Update Ball Physics ---
|
| 116 |
+
# Apply gravity
|
| 117 |
+
ball_velocity += gravity * dt
|
| 118 |
+
# Update position
|
| 119 |
+
ball_position += ball_velocity * dt
|
| 120 |
+
|
| 121 |
+
# --- Collision Detection & Response with Hexagon Edges ---
|
| 122 |
+
for i in range(len(hexagon_global)):
|
| 123 |
+
A = hexagon_global[i]
|
| 124 |
+
B = hexagon_global[(i + 1) % len(hexagon_global)]
|
| 125 |
+
# Compute the inward normal for this edge.
|
| 126 |
+
n = compute_inward_normal(A, B, hex_center)
|
| 127 |
+
|
| 128 |
+
# Find the closest point on the edge AB to the ball’s center.
|
| 129 |
+
closest = closest_point_on_segment(A, B, ball_position)
|
| 130 |
+
diff = ball_position - closest
|
| 131 |
+
dist = np.linalg.norm(diff)
|
| 132 |
+
|
| 133 |
+
if dist < ball_radius:
|
| 134 |
+
# --- Position Correction ---
|
| 135 |
+
penetration = ball_radius - dist
|
| 136 |
+
# Use the diff direction if available; otherwise fall back on edge normal.
|
| 137 |
+
if dist != 0:
|
| 138 |
+
correction_dir = diff / dist
|
| 139 |
+
else:
|
| 140 |
+
correction_dir = n
|
| 141 |
+
ball_position += correction_dir * penetration
|
| 142 |
+
|
| 143 |
+
# --- Collision Response ---
|
| 144 |
+
# Compute the velocity of the wall at the collision point due to rotation.
|
| 145 |
+
r = closest - hex_center
|
| 146 |
+
# In 2D, the tangential velocity due to rotation: v = ω x r,
|
| 147 |
+
# which can be computed as: v = ω * [-r_y, r_x]
|
| 148 |
+
v_wall = hex_angular_velocity * np.array([-r[1], r[0]])
|
| 149 |
+
|
| 150 |
+
# Compute the ball’s velocity relative to the wall.
|
| 151 |
+
v_rel = ball_velocity - v_wall
|
| 152 |
+
# Determine the component along the collision normal.
|
| 153 |
+
v_rel_normal = np.dot(v_rel, n)
|
| 154 |
+
|
| 155 |
+
# Only respond if the ball is moving into the wall.
|
| 156 |
+
if v_rel_normal < 0:
|
| 157 |
+
# Decompose the relative velocity into normal and tangential components.
|
| 158 |
+
v_n = v_rel_normal * n
|
| 159 |
+
v_t = v_rel - v_n
|
| 160 |
+
|
| 161 |
+
# Reflect the normal component (with restitution) and reduce the tangential
|
| 162 |
+
# component according to friction.
|
| 163 |
+
v_n_new = -restitution * v_n
|
| 164 |
+
v_t_new = (1 - friction_coef) * v_t
|
| 165 |
+
|
| 166 |
+
# Update ball velocity by adding back the wall’s velocity.
|
| 167 |
+
ball_velocity = v_wall + v_n_new + v_t_new
|
| 168 |
+
|
| 169 |
+
# --- Rendering ---
|
| 170 |
+
screen.fill((0, 0, 0)) # Dark background
|
| 171 |
+
|
| 172 |
+
# Draw the rotating hexagon.
|
| 173 |
+
hex_points = [(int(x), int(y)) for x, y in hexagon_global]
|
| 174 |
+
pygame.draw.polygon(screen, (255, 255, 255), hex_points, 3)
|
| 175 |
+
|
| 176 |
+
# Draw the ball.
|
| 177 |
+
pygame.draw.circle(screen, (255, 0, 0),
|
| 178 |
+
(int(ball_position[0]), int(ball_position[1])), ball_radius)
|
| 179 |
+
|
| 180 |
+
pygame.display.flip()
|
| 181 |
+
|
| 182 |
+
pygame.quit()
|
| 183 |
+
|
| 184 |
+
if __name__ == '__main__':
|
| 185 |
+
main()
|
examples/bouncing_ball_hexagon/mistral.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
system_prompt:
|
| 3 |
+
You are a helpful assistant. You write high quality code following best practises and employing the relevant packages for the task.
|
| 4 |
+
When dealing with code ensure it is coherent and that the implementation logic fully tackles the request you received.
|
| 5 |
+
|
| 6 |
+
temperature: 0
|
| 7 |
+
max_tokens: 3072
|
| 8 |
+
|
| 9 |
+
reasoner_system_prompt:
|
| 10 |
+
You are a helpfull assistant with reasoning capabilites that breaks down problems into at least 10 detailed steps with usefull thoughts on how to solve them.
|
| 11 |
+
|
| 12 |
+
temperature: 0.5
|
| 13 |
+
max_tokens: 2048
|
| 14 |
+
|
| 15 |
+
prompt:
|
| 16 |
+
write a python program that shows a ball bouncing inside a spninning hexagon. The ball should be affected by gravity and friction, and it must bounce off the rotating walls realistically.
|
| 17 |
+
"""
|
| 18 |
+
|
| 19 |
+
import pygame
|
| 20 |
+
import math
|
| 21 |
+
|
| 22 |
+
# Initialize Pygame
|
| 23 |
+
pygame.init()
|
| 24 |
+
|
| 25 |
+
# Screen dimensions
|
| 26 |
+
WIDTH, HEIGHT = 800, 600
|
| 27 |
+
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
| 28 |
+
pygame.display.set_caption("Bouncing Ball in Spinning Hexagon")
|
| 29 |
+
|
| 30 |
+
# Colors
|
| 31 |
+
WHITE = (255, 255, 255)
|
| 32 |
+
RED = (255, 0, 0)
|
| 33 |
+
BLACK = (0, 0, 0)
|
| 34 |
+
|
| 35 |
+
# Hexagon properties
|
| 36 |
+
hexagon_radius = 200
|
| 37 |
+
hexagon_angle = 0
|
| 38 |
+
hexagon_rotation_speed = 0.01 # radians per frame
|
| 39 |
+
|
| 40 |
+
# Ball properties
|
| 41 |
+
ball_radius = 20
|
| 42 |
+
ball_position = pygame.Vector2(WIDTH // 2, HEIGHT // 2)
|
| 43 |
+
ball_velocity = pygame.Vector2(-3, 15)
|
| 44 |
+
ball_acceleration = pygame.Vector2(0, 0.5) # Gravity
|
| 45 |
+
ball_friction = 0.99
|
| 46 |
+
ball_elasticity = 0.9
|
| 47 |
+
|
| 48 |
+
# Clock to control the frame rate
|
| 49 |
+
clock = pygame.time.Clock()
|
| 50 |
+
|
| 51 |
+
def calculate_hexagon_vertices(angle):
|
| 52 |
+
vertices = []
|
| 53 |
+
for i in range(6):
|
| 54 |
+
x = WIDTH // 2 + hexagon_radius * math.cos(angle + i * math.pi / 3)
|
| 55 |
+
y = HEIGHT // 2 + hexagon_radius * math.sin(angle + i * math.pi / 3)
|
| 56 |
+
vertices.append((x, y))
|
| 57 |
+
return vertices
|
| 58 |
+
|
| 59 |
+
def draw_hexagon(vertices):
|
| 60 |
+
pygame.draw.polygon(screen, WHITE, vertices, 2)
|
| 61 |
+
|
| 62 |
+
def draw_ball(position):
|
| 63 |
+
pygame.draw.circle(screen, RED, (int(position.x), int(position.y)), ball_radius)
|
| 64 |
+
|
| 65 |
+
def check_collision(ball_position, ball_velocity, vertices):
|
| 66 |
+
for i in range(6):
|
| 67 |
+
x1, y1 = vertices[i]
|
| 68 |
+
x2, y2 = vertices[(i + 1) % 6]
|
| 69 |
+
|
| 70 |
+
# Calculate the normal vector of the side
|
| 71 |
+
dx = x2 - x1
|
| 72 |
+
dy = y2 - y1
|
| 73 |
+
normal = pygame.Vector2(-dy, dx).normalize()
|
| 74 |
+
|
| 75 |
+
# Calculate the distance from the ball to the line
|
| 76 |
+
distance = abs((x2 - x1) * (y1 - ball_position.y) - (x1 - ball_position.x) * (y2 - y1)) / math.sqrt(dx**2 + dy**2)
|
| 77 |
+
|
| 78 |
+
if distance <= ball_radius:
|
| 79 |
+
# Collision detected, reflect the velocity
|
| 80 |
+
relative_velocity = ball_velocity.dot(normal)
|
| 81 |
+
if relative_velocity < 0:
|
| 82 |
+
ball_velocity.reflect_ip(normal)
|
| 83 |
+
ball_velocity *= ball_elasticity
|
| 84 |
+
ball_position += normal * (ball_radius - distance)
|
| 85 |
+
|
| 86 |
+
# Main loop
|
| 87 |
+
running = True
|
| 88 |
+
while running:
|
| 89 |
+
for event in pygame.event.get():
|
| 90 |
+
if event.type == pygame.QUIT:
|
| 91 |
+
running = False
|
| 92 |
+
|
| 93 |
+
# Update hexagon angle
|
| 94 |
+
hexagon_angle += hexagon_rotation_speed
|
| 95 |
+
|
| 96 |
+
# Calculate hexagon vertices
|
| 97 |
+
vertices = calculate_hexagon_vertices(hexagon_angle)
|
| 98 |
+
|
| 99 |
+
# Apply gravity and friction to the ball
|
| 100 |
+
ball_velocity += ball_acceleration
|
| 101 |
+
ball_velocity *= ball_friction
|
| 102 |
+
ball_position += ball_velocity
|
| 103 |
+
|
| 104 |
+
# Check for collisions with hexagon sides
|
| 105 |
+
check_collision(ball_position, ball_velocity, vertices)
|
| 106 |
+
|
| 107 |
+
# Draw everything
|
| 108 |
+
screen.fill(BLACK)
|
| 109 |
+
draw_hexagon(vertices)
|
| 110 |
+
draw_ball(ball_position)
|
| 111 |
+
pygame.display.flip()
|
| 112 |
+
|
| 113 |
+
# Cap the frame rate
|
| 114 |
+
clock.tick(60)
|
| 115 |
+
|
| 116 |
+
pygame.quit()
|
examples/bouncing_ball_hexagon/mistral_no_reasoner.py
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pygame
|
| 2 |
+
import math
|
| 3 |
+
import random
|
| 4 |
+
|
| 5 |
+
# Initialize Pygame
|
| 6 |
+
pygame.init()
|
| 7 |
+
|
| 8 |
+
# Screen dimensions
|
| 9 |
+
WIDTH, HEIGHT = 800, 600
|
| 10 |
+
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
| 11 |
+
pygame.display.set_caption("Bouncing Ball in Spinning Hexagon")
|
| 12 |
+
|
| 13 |
+
# Colors
|
| 14 |
+
WHITE = (255, 255, 255)
|
| 15 |
+
BLACK = (0, 0, 0)
|
| 16 |
+
RED = (255, 0, 0)
|
| 17 |
+
|
| 18 |
+
# Ball properties
|
| 19 |
+
ball_radius = 10
|
| 20 |
+
ball_pos = [WIDTH // 2, HEIGHT // 2]
|
| 21 |
+
ball_vel = [random.uniform(-2, 2), random.uniform(-2, 2)]
|
| 22 |
+
gravity = 0.3
|
| 23 |
+
friction = 1.2
|
| 24 |
+
|
| 25 |
+
# Hexagon properties
|
| 26 |
+
hexagon_radius = 150
|
| 27 |
+
hexagon_angle = 0
|
| 28 |
+
hexagon_rotation_speed = 0.005 # radians per frame
|
| 29 |
+
|
| 30 |
+
def draw_hexagon(surface, color, radius, angle, center):
|
| 31 |
+
points = []
|
| 32 |
+
for i in range(6):
|
| 33 |
+
x = center[0] + radius * math.cos(angle + i * math.pi / 3)
|
| 34 |
+
y = center[1] + radius * math.sin(angle + i * math.pi / 3)
|
| 35 |
+
points.append((x, y))
|
| 36 |
+
pygame.draw.polygon(surface, color, points, 2)
|
| 37 |
+
|
| 38 |
+
def is_point_inside_hexagon(point, radius, angle, center):
|
| 39 |
+
for i in range(6):
|
| 40 |
+
x1 = center[0] + radius * math.cos(angle + i * math.pi / 3)
|
| 41 |
+
y1 = center[1] + radius * math.sin(angle + i * math.pi / 3)
|
| 42 |
+
x2 = center[0] + radius * math.cos(angle + (i + 1) * math.pi / 3)
|
| 43 |
+
y2 = center[1] + radius * math.sin(angle + (i + 1) * math.pi / 3)
|
| 44 |
+
if intersects(point, ball_radius, (x1, y1), (x2, y2)):
|
| 45 |
+
return True
|
| 46 |
+
return False
|
| 47 |
+
|
| 48 |
+
def intersects(point, radius, p1, p2):
|
| 49 |
+
# Check if the circle intersects the line segment
|
| 50 |
+
dx = p2[0] - p1[0]
|
| 51 |
+
dy = p2[1] - p1[1]
|
| 52 |
+
t = ((point[0] - p1[0]) * dx + (point[1] - p1[1]) * dy) / (dx * dx + dy * dy)
|
| 53 |
+
if t < 0:
|
| 54 |
+
closest = p1
|
| 55 |
+
elif t > 1:
|
| 56 |
+
closest = p2
|
| 57 |
+
else:
|
| 58 |
+
closest = (p1[0] + t * dx, p1[1] + t * dy)
|
| 59 |
+
distance = math.hypot(point[0] - closest[0], point[1] - closest[1])
|
| 60 |
+
return distance <= radius
|
| 61 |
+
|
| 62 |
+
def reflect_velocity(vel, normal):
|
| 63 |
+
dot_product = vel[0] * normal[0] + vel[1] * normal[1]
|
| 64 |
+
vel[0] = vel[0] - 2 * dot_product * normal[0]
|
| 65 |
+
vel[1] = vel[1] - 2 * dot_product * normal[1]
|
| 66 |
+
|
| 67 |
+
# Main loop
|
| 68 |
+
running = True
|
| 69 |
+
clock = pygame.time.Clock()
|
| 70 |
+
|
| 71 |
+
while running:
|
| 72 |
+
for event in pygame.event.get():
|
| 73 |
+
if event.type == pygame.QUIT:
|
| 74 |
+
running = False
|
| 75 |
+
|
| 76 |
+
# Update ball position
|
| 77 |
+
ball_vel[1] += gravity
|
| 78 |
+
ball_pos[0] += ball_vel[0]
|
| 79 |
+
ball_pos[1] += ball_vel[1]
|
| 80 |
+
|
| 81 |
+
# Check for collision with hexagon walls
|
| 82 |
+
if is_point_inside_hexagon(ball_pos, hexagon_radius, hexagon_angle, (WIDTH // 2, HEIGHT // 2)):
|
| 83 |
+
for i in range(6):
|
| 84 |
+
x1 = WIDTH // 2 + hexagon_radius * math.cos(hexagon_angle + i * math.pi / 3)
|
| 85 |
+
y1 = HEIGHT // 2 + hexagon_radius * math.sin(hexagon_angle + i * math.pi / 3)
|
| 86 |
+
x2 = WIDTH // 2 + hexagon_radius * math.cos(hexagon_angle + (i + 1) * math.pi / 3)
|
| 87 |
+
y2 = HEIGHT // 2 + hexagon_radius * math.sin(hexagon_angle + (i + 1) * math.pi / 3)
|
| 88 |
+
if intersects(ball_pos, ball_radius, (x1, y1), (x2, y2)):
|
| 89 |
+
normal = (y2 - y1, x1 - x2)
|
| 90 |
+
normal_length = math.hypot(normal[0], normal[1])
|
| 91 |
+
normal = (normal[0] / normal_length, normal[1] / normal_length)
|
| 92 |
+
reflect_velocity(ball_vel, normal)
|
| 93 |
+
ball_vel[0] *= friction
|
| 94 |
+
ball_vel[1] *= friction
|
| 95 |
+
break
|
| 96 |
+
|
| 97 |
+
# Update hexagon angle
|
| 98 |
+
hexagon_angle += hexagon_rotation_speed
|
| 99 |
+
|
| 100 |
+
# Draw everything
|
| 101 |
+
screen.fill(BLACK)
|
| 102 |
+
draw_hexagon(screen, WHITE, hexagon_radius, hexagon_angle, (WIDTH // 2, HEIGHT // 2))
|
| 103 |
+
pygame.draw.circle(screen, RED, (int(ball_pos[0]), int(ball_pos[1])), ball_radius)
|
| 104 |
+
pygame.display.flip()
|
| 105 |
+
|
| 106 |
+
# Cap the frame rate
|
| 107 |
+
clock.tick(60)
|
| 108 |
+
|
| 109 |
+
pygame.quit()
|