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:

  1. Forces and Torques
  2. Collision Response
  3. Momentum and Impulse
  4. Practical Examples
  5. 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.

© Copyright 2024. All rights reserved