In this section, we will delve into the interactions between rigid bodies in a video game environment. Understanding these interactions is crucial for creating realistic and engaging simulations. We will cover the following topics:
- Forces and Torques
- Collision Response
- Momentum and Impulse
- Practical Examples
- Exercises
Forces and Torques
Forces
Forces are vectors that cause objects to accelerate. In the context of rigid bodies, forces can be applied at any point on the body, and they can cause both linear and angular acceleration.
Key Concepts:
- Newton's Second Law: \( F = ma \)
- Force Types: Gravity, friction, normal force, applied force, etc.
Torques
Torque is a measure of the rotational force applied to an object. It depends on the force applied and the distance from the point of application to the axis of rotation.
Key Concepts:
- Torque Formula: \( \tau = r \times F \)
- \( \tau \) is the torque
- \( r \) is the position vector from the axis of rotation to the point of force application
- \( F \) is the force vector
Example Code: Applying Forces and Torques
class RigidBody: def __init__(self, mass, inertia, position, velocity, angular_velocity): self.mass = mass self.inertia = inertia self.position = position self.velocity = velocity self.angular_velocity = angular_velocity self.force = [0, 0] self.torque = 0 def apply_force(self, force, point): self.force[0] += force[0] self.force[1] += force[1] self.torque += point[0] * force[1] - point[1] * force[0] def update(self, dt): # Linear motion acceleration = [self.force[0] / self.mass, self.force[1] / self.mass] self.velocity[0] += acceleration[0] * dt self.velocity[1] += acceleration[1] * dt self.position[0] += self.velocity[0] * dt self.position[1] += self.velocity[1] * dt # Angular motion angular_acceleration = self.torque / self.inertia self.angular_velocity += angular_acceleration * dt # Reset forces and torques self.force = [0, 0] self.torque = 0 # Example usage rigid_body = RigidBody(mass=10, inertia=5, position=[0, 0], velocity=[0, 0], angular_velocity=0) rigid_body.apply_force([10, 0], [1, 0]) rigid_body.update(0.1) print(rigid_body.position, rigid_body.velocity, rigid_body.angular_velocity)
Collision Response
When two rigid bodies collide, they exert forces on each other that change their velocities. The response to a collision depends on the properties of the bodies and the nature of the collision.
Key Concepts:
- Elastic and Inelastic Collisions: In elastic collisions, kinetic energy is conserved. In inelastic collisions, some kinetic energy is converted to other forms of energy.
- Coefficient of Restitution (e): Measures the elasticity of a collision. \( e = 1 \) for perfectly elastic collisions and \( e = 0 \) for perfectly inelastic collisions.
Example Code: Collision Response
def resolve_collision(body1, body2, collision_normal, restitution): relative_velocity = [body2.velocity[0] - body1.velocity[0], body2.velocity[1] - body1.velocity[1]] velocity_along_normal = relative_velocity[0] * collision_normal[0] + relative_velocity[1] * collision_normal[1] if velocity_along_normal > 0: return impulse_magnitude = -(1 + restitution) * velocity_along_normal impulse_magnitude /= (1 / body1.mass + 1 / body2.mass) impulse = [impulse_magnitude * collision_normal[0], impulse_magnitude * collision_normal[1]] body1.velocity[0] -= impulse[0] / body1.mass body1.velocity[1] -= impulse[1] / body1.mass body2.velocity[0] += impulse[0] / body2.mass body2.velocity[1] += impulse[1] / body2.mass # Example usage body1 = RigidBody(mass=10, inertia=5, position=[0, 0], velocity=[5, 0], angular_velocity=0) body2 = RigidBody(mass=10, inertia=5, position=[1, 0], velocity=[-5, 0], angular_velocity=0) resolve_collision(body1, body2, [1, 0], 0.8) print(body1.velocity, body2.velocity)
Momentum and Impulse
Momentum
Momentum is the product of an object's mass and velocity. It is a vector quantity.
Formula: \( p = mv \)
Impulse
Impulse is the change in momentum resulting from a force applied over a period of time.
Formula: \( J = F \Delta t \)
Example Code: Momentum and Impulse
def apply_impulse(body, impulse): body.velocity[0] += impulse[0] / body.mass body.velocity[1] += impulse[1] / body.mass # Example usage body = RigidBody(mass=10, inertia=5, position=[0, 0], velocity=[0, 0], angular_velocity=0) impulse = [10, 0] apply_impulse(body, impulse) print(body.velocity)
Practical Examples
Example: Bouncing Ball
class BouncingBall(RigidBody): def __init__(self, mass, inertia, position, velocity, angular_velocity, radius): super().__init__(mass, inertia, position, velocity, angular_velocity) self.radius = radius def check_collision_with_ground(self, ground_level, restitution): if self.position[1] - self.radius < ground_level: self.position[1] = ground_level + self.radius self.velocity[1] = -self.velocity[1] * restitution # Example usage ball = BouncingBall(mass=1, inertia=0.1, position=[0, 10], velocity=[0, -5], angular_velocity=0, radius=1) dt = 0.1 for _ in range(100): ball.update(dt) ball.check_collision_with_ground(ground_level=0, restitution=0.9) print(ball.position, ball.velocity)
Exercises
Exercise 1: Applying Forces
Task: Create a function to apply a force to a rigid body at a given point and update its position and velocity.
Solution:
def apply_force_and_update(body, force, point, dt): body.apply_force(force, point) body.update(dt) # Test the function body = RigidBody(mass=10, inertia=5, position=[0, 0], velocity=[0, 0], angular_velocity=0) apply_force_and_update(body, [10, 0], [1, 0], 0.1) print(body.position, body.velocity, body.angular_velocity)
Exercise 2: Collision Response
Task: Implement a collision response function for two rigid bodies and test it with different restitution values.
Solution:
def test_collision_response(): body1 = RigidBody(mass=10, inertia=5, position=[0, 0], velocity=[5, 0], angular_velocity=0) body2 = RigidBody(mass=10, inertia=5, position=[1, 0], velocity=[-5, 0], angular_velocity=0) resolve_collision(body1, body2, [1, 0], 0.8) print("After collision with restitution 0.8:", body1.velocity, body2.velocity) body1.velocity = [5, 0] body2.velocity = [-5, 0] resolve_collision(body1, body2, [1, 0], 0.5) print("After collision with restitution 0.5:", body1.velocity, body2.velocity) test_collision_response()
Conclusion
In this section, we explored the interactions between rigid bodies, focusing on forces, torques, collision response, and momentum. We provided practical examples and exercises to reinforce these concepts. Understanding these interactions is fundamental for simulating realistic physical behaviors in video games. In the next section, we will delve into constraints and joints, which are essential for creating complex and interconnected systems of rigid bodies.
Physics of Video Games
Module 1: Introduction to Physics in Video Games
Module 2: Kinematics and Dynamics
- Uniform Rectilinear Motion (URM)
- Uniformly Accelerated Rectilinear Motion (UARM)
- Newton's Laws
- Circular Motion
Module 3: Collisions and Responses
Module 4: Rigid Bodies Physics
- Introduction to Rigid Bodies
- Rigid Bodies Simulation
- Interactions between Rigid Bodies
- Constraints and Joints