moved physics into its own class in physics.py
All checks were successful
Build Simulation and Test / Run All Tests (push) Successful in 2m56s
All checks were successful
Build Simulation and Test / Run All Tests (push) Successful in 2m56s
This commit is contained in:
parent
8f17498b88
commit
7289543f6a
@ -9,6 +9,7 @@ import pygame
|
|||||||
from typing import Optional, List, Any, Union
|
from typing import Optional, List, Any, Union
|
||||||
|
|
||||||
from world.utils import get_distance_between_objects
|
from world.utils import get_distance_between_objects
|
||||||
|
from world.physics import Physics
|
||||||
|
|
||||||
from math import atan2, degrees
|
from math import atan2, degrees
|
||||||
|
|
||||||
@ -263,6 +264,8 @@ class DefaultCell(BaseEntity):
|
|||||||
|
|
||||||
self.tick_count = 0
|
self.tick_count = 0
|
||||||
|
|
||||||
|
self.physics = Physics(0.02, 0.05)
|
||||||
|
|
||||||
|
|
||||||
def set_brain(self, behavioral_model: CellBrain) -> None:
|
def set_brain(self, behavioral_model: CellBrain) -> None:
|
||||||
self.behavioral_model = behavioral_model
|
self.behavioral_model = behavioral_model
|
||||||
@ -328,44 +331,12 @@ class DefaultCell(BaseEntity):
|
|||||||
|
|
||||||
output_data = self.behavioral_model.tick(input_data)
|
output_data = self.behavioral_model.tick(input_data)
|
||||||
|
|
||||||
# everything below this point is physics simulation and needs to be extracted to a separate class
|
|
||||||
|
|
||||||
# clamp accelerations
|
# clamp accelerations
|
||||||
output_data["linear_acceleration"] = max(-MAX_ACCELERATION, min(MAX_ACCELERATION, output_data["linear_acceleration"]))
|
output_data["linear_acceleration"] = max(-MAX_ACCELERATION, min(MAX_ACCELERATION, output_data["linear_acceleration"]))
|
||||||
output_data["angular_acceleration"] = max(-MAX_ANGULAR_ACCELERATION, min(MAX_ANGULAR_ACCELERATION, output_data["angular_acceleration"]))
|
output_data["angular_acceleration"] = max(-MAX_ANGULAR_ACCELERATION, min(MAX_ANGULAR_ACCELERATION, output_data["angular_acceleration"]))
|
||||||
|
|
||||||
# 2. Apply drag force
|
# request physics data from Physics class
|
||||||
drag_coefficient = 0.02
|
self.velocity, self.acceleration, self.rotational_velocity, self.angular_acceleration = self.physics.move(output_data["linear_acceleration"], output_data["angular_acceleration"], self.rotation.get_rotation())
|
||||||
drag_x = -self.velocity[0] * drag_coefficient
|
|
||||||
drag_y = -self.velocity[1] * drag_coefficient
|
|
||||||
|
|
||||||
# 3. Combine all forces
|
|
||||||
total_linear_accel = output_data["linear_acceleration"]
|
|
||||||
total_linear_accel = max(-0.1, min(0.1, total_linear_accel))
|
|
||||||
|
|
||||||
# 4. Convert to world coordinates
|
|
||||||
x_component = total_linear_accel * math.cos(math.radians(self.rotation.get_rotation()))
|
|
||||||
y_component = total_linear_accel * math.sin(math.radians(self.rotation.get_rotation()))
|
|
||||||
|
|
||||||
# 5. Add drag to total acceleration
|
|
||||||
total_accel_x = x_component + drag_x
|
|
||||||
total_accel_y = y_component + drag_y
|
|
||||||
|
|
||||||
self.acceleration = (total_accel_x, total_accel_y)
|
|
||||||
|
|
||||||
rotational_drag = 0.05
|
|
||||||
self.angular_acceleration = output_data["angular_acceleration"] - self.rotational_velocity * rotational_drag
|
|
||||||
|
|
||||||
# tick acceleration
|
|
||||||
velocity_x = self.velocity[0] + self.acceleration[0]
|
|
||||||
velocity_y = self.velocity[1] + self.acceleration[1]
|
|
||||||
self.velocity = (velocity_x, velocity_y)
|
|
||||||
|
|
||||||
# # clamp velocity
|
|
||||||
speed = math.sqrt(self.velocity[0] ** 2 + self.velocity[1] ** 2)
|
|
||||||
if speed > MAX_VELOCITY:
|
|
||||||
scale = MAX_VELOCITY / speed
|
|
||||||
self.velocity = (self.velocity[0] * scale, self.velocity[1] * scale)
|
|
||||||
|
|
||||||
# tick velocity
|
# tick velocity
|
||||||
x, y = self.position.get_position()
|
x, y = self.position.get_position()
|
||||||
@ -374,13 +345,6 @@ class DefaultCell(BaseEntity):
|
|||||||
|
|
||||||
self.position.set_position(x, y)
|
self.position.set_position(x, y)
|
||||||
|
|
||||||
# tick rotational acceleration
|
|
||||||
self.angular_acceleration = output_data["angular_acceleration"]
|
|
||||||
self.rotational_velocity += self.angular_acceleration
|
|
||||||
|
|
||||||
# clamp rotational velocity
|
|
||||||
self.rotational_velocity = max(-MAX_ROTATIONAL_VELOCITY, min(MAX_ROTATIONAL_VELOCITY, self.rotational_velocity))
|
|
||||||
|
|
||||||
# tick rotational velocity
|
# tick rotational velocity
|
||||||
self.rotation.set_rotation(self.rotation.get_rotation() + self.rotational_velocity)
|
self.rotation.set_rotation(self.rotation.get_rotation() + self.rotational_velocity)
|
||||||
|
|
||||||
|
|||||||
104
world/physics.py
Normal file
104
world/physics.py
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
|
from config.constants import MAX_VELOCITY, MAX_ROTATIONAL_VELOCITY
|
||||||
|
|
||||||
|
|
||||||
|
class Physics:
|
||||||
|
"""
|
||||||
|
Physics
|
||||||
|
⠀⠀⢀⣀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡠⣄⠀⠀⠀⠀⠀
|
||||||
|
⠀⣴⠊⠛⠦⣅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⠈⠈⠳⡄⠀⠀⠀
|
||||||
|
⠸⣿⠀⠀⠀⠉⢹⣆⠀⠀⠀⠠⡶⠖⢦⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢻⡄⠀⠀⠈⡆⠀⠀
|
||||||
|
⠀⠈⣧⠀⠀⠀⠀⠉⠓⠂⠐⠋⠀⠀⢸⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⡆⢀⢰⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡒⠀⣤⢀⠀⠈⡇⠀⠀⠀⢹⡂⠀
|
||||||
|
⠀⠀⢹⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠰⠞⠄⠀⠀⠀⠀⠀⠀⠀⣀⣤⣾⠿⠁⠈⠁⠉⠻⢷⠶⠴⢭⡄⠤⡀⠀⠀⠀⠀⠀⢿⡇⠀⠈⢢⠀⣸⡇⠀⠀⠀⠐⠁⠀
|
||||||
|
⠀⠀⠀⢻⠀⠀⠀⠀⠀⠀⠀⠀⢐⡏⡀⠀⠀⠀⠀⠀⠀⣠⡚⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠑⢮⡀⡀⠀⠀⠀⠉⢳⡄⠀⡘⠛⠋⠀⠀⠀⠀⠀⡄⠀
|
||||||
|
⠀⠀⠀⢀⣇⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⢀⣴⠏⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⣌⢂⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⢰⣧⡅
|
||||||
|
⠀⠀⠀⠀⢻⣄⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⣠⡾⠁⠀⠀⠀⠀⠀⣠⡴⠖⠤⠴⠤⠶⠀⢄⠀⠀⠀⠀⠀⠀⠈⠓⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⢠⣤⠞⠵⠁
|
||||||
|
⠀⠀⠀⠀⠀⠻⣦⡀⠀⠀⠀⢰⡺⠀⠀⠀⢀⡾⠇⠀⠀⠀⠀⣠⡾⠋⠀⠀⠀⠀⠀⠀⠀⠀⢹⣀⡀⠀⠀⠀⠀⠀⢱⠀⠀⠘⠛⢧⡀⠀⠀⣀⣴⠟⠁⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠈⠓⠖⠶⠶⠵⠃⠀⠀⠀⢺⢈⠀⠀⠀⢀⣰⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠙⢆⠀⠀⠀⠀⠀⠸⣄⠁⠀⠀⠈⠻⠒⠚⠏⠁⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢘⡀⠀⠀⠀⢸⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣡⡀⠀⠀⠀⠀⢸⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠃⠀⠀⣠⡎⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⠀⠀⠀⠀⢻⡁⡀⠀⠀⢀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡔⠀⠀⡾⠀⠀⠀⠀⢀⡤⠞⠁⠀⠀⠀⠹⠄⠀⠀⠀⠈⢯⠀⠀⠀⣠⣼⠅⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠿⣧⠀⢸⡇⠀⠀⢠⡼⠋⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⠀⠀⠸⡄⠀⢀⣿⣏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⣄⣸⡁⠀⢀⠾⡆⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠀⠀⢠⡣⠀⣸⡿⠂⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠿⣬⠛⠁⡆⠉⡆⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠂⢧⠀⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣆⣀⣁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠀⢀⣸⣤⣿⠯⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠀⠘⠳⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⠿⠋⠛⠛⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠙⠛⠲⠖⠒⠒⠂⠒⠒⠒⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
||||||
|
|
||||||
|
⣿⣿⣿⣿⣿⣿⣿⣿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣹⡏⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣿⣿⣧⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⢻⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣿⠿⣋⡁⢶⣦⣤⣍⠙⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⠉⡴⣿⡟⢸⣿⣿⡿⣷⡄⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⡿⢸⣿⣿⡗⣼⣿⣿⣯⣽⢻⡆⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⡇⣾⣿⣿⣾⣿⣿⣾⣿⣯⣿⣧⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⡟⣱⣿⣿⣿⣿⣿⣽⣾⣿⣽⢻⣏⡄⣿⢿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⡿⢡⣿⣯⣿⣿⡿⣟⣻⣿⣿⢿⣿⣏⢻⠘⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⠗⠒⣛⢻⣿⣿⣿⡟⢻⣿⣏⣿⣷⣠⣿⡘⡧⡘⢿⣿⣿⣿⣿⣿⣿
|
||||||
|
⠛⠁⢴⠺⢿⡀⠻⣿⢿⡇⣼⠏⠯⠈⢿⡿⢘⣿⡘⣦⡘⣿⣿⣿⣿⣿⣿
|
||||||
|
⠀⠀⠀⠀⠈⢻⡆⠈⠈⢠⡇⠐⠀⠀⠈⠃⢸⣯⣧⠉⣧⠸⣿⣿⣿⣿⣿
|
||||||
|
⡄⣀⢃⠀⠀⣸⣿⣧⡀⣼⣿⡀⠀⠀⢠⡄⠸⣿⣿⣷⢉⠃⣿⣿⣿⣿⣿
|
||||||
|
⡇⢹⣦⡻⣿⣿⣿⢩⣷⣿⣿⣿⣷⣾⣾⠇⣶⣞⡛⣷⣌⡀⣿⣿⣿⣿⣿
|
||||||
|
⡶⢄⠻⣿⣾⣿⠓⠬⠽⠟⢛⣿⣿⣿⣟⢐⢻⣿⣿⣿⠿⢡⣿⣿⣿⣿⣿
|
||||||
|
⣿⣇⢱⠙⢿⣿⣶⣖⣲⣶⣿⣿⡿⢋⣡⣿⣿⣿⣿⡟⢠⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣷⣅⢲⣌⠛⠿⠿⠿⢟⠁⣴⣷⣾⣿⣾⡿⠟⣰⣿⣷⣮⣭⣭⣟⣻
|
||||||
|
⣿⣿⣿⣿⣷⣌⡐⠰⣴⣶⠾⠿⢿⠿⠷⠟⠈⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣧⠀⠀⠀⠉⠁⠀⢀⣀⣠⣴⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣿⣷⣶⣬⣘⣒⠷⢦⣶⣶⣶⣗⣿⣿⣿⣿⣿⣿⣿⣿⣿
|
||||||
|
⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣶⣶⣾⣿⣿⣟⣛⣿⣿⣿⣿⣿⣿
|
||||||
|
"""
|
||||||
|
def __init__(self, drag_coefficient: float, rotational_drag: float):
|
||||||
|
self.drag_coefficient: float = drag_coefficient
|
||||||
|
self.rotational_drag: float = rotational_drag
|
||||||
|
|
||||||
|
self.velocity: tuple[int, int] = (0, 0)
|
||||||
|
self.acceleration: tuple[int, int] = (0, 0)
|
||||||
|
|
||||||
|
self.rotational_velocity: int = 0
|
||||||
|
self.angular_acceleration: int = 0
|
||||||
|
|
||||||
|
|
||||||
|
def move(self, linear_acceleration: float, angular_acceleration: int, rotational_position):
|
||||||
|
# Apply drag force
|
||||||
|
drag_coefficient = self.drag_coefficient
|
||||||
|
drag_x = -self.velocity[0] * drag_coefficient
|
||||||
|
drag_y = -self.velocity[1] * drag_coefficient
|
||||||
|
|
||||||
|
# Combine all forces
|
||||||
|
total_linear_accel = linear_acceleration
|
||||||
|
total_linear_accel = max(-0.1, min(0.1, total_linear_accel))
|
||||||
|
|
||||||
|
# Convert to world coordinates
|
||||||
|
x_component = total_linear_accel * math.cos(math.radians(rotational_position))
|
||||||
|
y_component = total_linear_accel * math.sin(math.radians(rotational_position))
|
||||||
|
|
||||||
|
# Add drag to total acceleration
|
||||||
|
total_accel_x = x_component + drag_x
|
||||||
|
total_accel_y = y_component + drag_y
|
||||||
|
|
||||||
|
self.acceleration = (total_accel_x, total_accel_y)
|
||||||
|
|
||||||
|
# Apply drag force to angular acceleration
|
||||||
|
rotational_drag = self.rotational_drag
|
||||||
|
self.angular_acceleration = angular_acceleration - self.rotational_velocity * rotational_drag
|
||||||
|
|
||||||
|
# tick acceleration
|
||||||
|
velocity_x = self.velocity[0] + self.acceleration[0]
|
||||||
|
velocity_y = self.velocity[1] + self.acceleration[1]
|
||||||
|
self.velocity = (velocity_x, velocity_y)
|
||||||
|
|
||||||
|
# # clamp velocity
|
||||||
|
speed = math.sqrt(self.velocity[0] ** 2 + self.velocity[1] ** 2)
|
||||||
|
if speed > MAX_VELOCITY:
|
||||||
|
scale = MAX_VELOCITY / speed
|
||||||
|
self.velocity = (self.velocity[0] * scale, self.velocity[1] * scale)
|
||||||
|
|
||||||
|
self.angular_acceleration = angular_acceleration
|
||||||
|
self.rotational_velocity += self.angular_acceleration
|
||||||
|
|
||||||
|
# clamp rotational velocity
|
||||||
|
self.rotational_velocity = max(-MAX_ROTATIONAL_VELOCITY, min(MAX_ROTATIONAL_VELOCITY, self.rotational_velocity))
|
||||||
|
|
||||||
|
return self.velocity, self.acceleration, self.rotational_velocity, self.angular_acceleration
|
||||||
Loading…
x
Reference in New Issue
Block a user