Collision resolution is a critical aspect of video game physics that ensures realistic interactions between objects after a collision is detected. This involves calculating the resulting velocities, positions, and sometimes rotations of the colliding objects. In this section, we will cover the fundamental principles and techniques used to resolve collisions in video games.
Key Concepts
- Impulse-Based Resolution: This method applies an instantaneous change in velocity to the colliding objects to resolve the collision.
- Penetration Depth: The measure of how much one object has penetrated another during a collision.
- Restitution Coefficient: A value that determines the elasticity of a collision, affecting how much kinetic energy is conserved.
- Friction: The force that resists the relative motion of objects in contact.
Impulse-Based Collision Resolution
Impulse-based collision resolution is one of the most common methods used in video games. It involves applying an impulse to the colliding objects to change their velocities instantaneously, ensuring they move apart.
Steps to Resolve a Collision Using Impulse
- Calculate Relative Velocity: Determine the relative velocity of the two colliding objects at the point of contact.
- Compute Normal and Tangential Components: Decompose the relative velocity into normal and tangential components relative to the collision normal.
- Calculate Impulse Magnitude: Use the restitution coefficient and the normal component of the relative velocity to compute the impulse magnitude.
- Apply Impulse: Adjust the velocities of the colliding objects by applying the calculated impulse.
Example
Consider two objects, A and B, with masses \( m_A \) and \( m_B \), initial velocities \( v_A \) and \( v_B \), and a collision normal \( n \).
# Given values m_A = 2.0 # mass of object A m_B = 3.0 # mass of object B v_A = [5.0, 0.0] # velocity of object A v_B = [-2.0, 0.0] # velocity of object B n = [1.0, 0.0] # collision normal restitution = 0.8 # coefficient of restitution # Calculate relative velocity relative_velocity = [v_B[0] - v_A[0], v_B[1] - v_A[1]] # Calculate normal component of relative velocity relative_velocity_normal = (relative_velocity[0] * n[0] + relative_velocity[1] * n[1]) # Calculate impulse scalar impulse_scalar = -(1 + restitution) * relative_velocity_normal / (1/m_A + 1/m_B) # Calculate impulse vector impulse = [impulse_scalar * n[0], impulse_scalar * n[1]] # Apply impulse to object A v_A[0] += impulse[0] / m_A v_A[1] += impulse[1] / m_A # Apply impulse to object B v_B[0] -= impulse[0] / m_B v_B[1] -= impulse[1] / m_B print("New velocity of object A:", v_A) print("New velocity of object B:", v_B)
Explanation
- Relative Velocity: The relative velocity between objects A and B is calculated.
- Normal Component: The normal component of the relative velocity is computed using the dot product with the collision normal.
- Impulse Scalar: The impulse scalar is calculated using the restitution coefficient and the normal component of the relative velocity.
- Impulse Vector: The impulse vector is derived by multiplying the impulse scalar with the collision normal.
- Apply Impulse: The impulse is applied to both objects, adjusting their velocities accordingly.
Penetration Depth and Position Correction
In addition to resolving velocities, it is often necessary to correct the positions of the colliding objects to prevent them from overlapping.
Position Correction Methods
- Linear Projection: Move the objects apart along the collision normal by a distance proportional to the penetration depth.
- Baumgarte Stabilization: A method that applies a corrective force over time to reduce penetration.
Example
# Given values penetration_depth = 0.5 # depth of penetration correction_factor = 0.8 # correction factor # Calculate position correction correction = [penetration_depth * n[0] * correction_factor, penetration_depth * n[1] * correction_factor] # Apply position correction to object A position_A = [position_A[0] - correction[0] / 2, position_A[1] - correction[1] / 2] # Apply position correction to object B position_B = [position_B[0] + correction[0] / 2, position_B[1] + correction[1] / 2] print("New position of object A:", position_A) print("New position of object B:", position_B)
Practical Exercise
Exercise
Given two objects with the following properties, resolve their collision using impulse-based resolution and correct their positions:
- Object A: mass = 1.5, velocity = [3.0, 1.0], position = [2.0, 2.0]
- Object B: mass = 2.5, velocity = [-1.0, -1.0], position = [3.0, 2.0]
- Collision normal = [1.0, 0.0]
- Restitution coefficient = 0.6
- Penetration depth = 0.3
Solution
# Given values m_A = 1.5 m_B = 2.5 v_A = [3.0, 1.0] v_B = [-1.0, -1.0] position_A = [2.0, 2.0] position_B = [3.0, 2.0] n = [1.0, 0.0] restitution = 0.6 penetration_depth = 0.3 correction_factor = 0.8 # Calculate relative velocity relative_velocity = [v_B[0] - v_A[0], v_B[1] - v_A[1]] # Calculate normal component of relative velocity relative_velocity_normal = (relative_velocity[0] * n[0] + relative_velocity[1] * n[1]) # Calculate impulse scalar impulse_scalar = -(1 + restitution) * relative_velocity_normal / (1/m_A + 1/m_B) # Calculate impulse vector impulse = [impulse_scalar * n[0], impulse_scalar * n[1]] # Apply impulse to object A v_A[0] += impulse[0] / m_A v_A[1] += impulse[1] / m_A # Apply impulse to object B v_B[0] -= impulse[0] / m_B v_B[1] -= impulse[1] / m_B # Calculate position correction correction = [penetration_depth * n[0] * correction_factor, penetration_depth * n[1] * correction_factor] # Apply position correction to object A position_A = [position_A[0] - correction[0] / 2, position_A[1] - correction[1] / 2] # Apply position correction to object B position_B = [position_B[0] + correction[0] / 2, position_B[1] + correction[1] / 2] print("New velocity of object A:", v_A) print("New velocity of object B:", v_B) print("New position of object A:", position_A) print("New position of object B:", position_B)
Explanation
- Relative Velocity: Calculate the relative velocity between the two objects.
- Normal Component: Compute the normal component of the relative velocity.
- Impulse Scalar: Calculate the impulse scalar using the restitution coefficient.
- Impulse Vector: Derive the impulse vector.
- Apply Impulse: Adjust the velocities of both objects.
- Position Correction: Correct the positions of the objects to resolve penetration.
Summary
In this section, we covered the fundamental principles of collision resolution in video games. We discussed impulse-based collision resolution, position correction methods, and provided practical examples and exercises to reinforce the concepts. Understanding and implementing these techniques is crucial for creating realistic and engaging interactions in video games.
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