Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / 2D

Making a 2D Physics Engine: Spaces and Bodies

4.50/5 (9 votes)
29 Jan 2018CPOL3 min read 17.4K  
The basics of spaces, transformations and bodies used in a 2D physics engine.

Making a 2D Physics Engine: The Series

This is the second article in the Making a 2D Physics Engine Series. If you haven't already read all the articles in the series before this one, I strongly recommend that you take a detour and skim through them.

  1. Making a 2D Physics Engine: The Math
  2. Making a 2D Physics Engine: Spaces and Bodies
  3. Making a 2D Physics Engine: Shapes, Worlds and Integration
  4. Making a 2D Physics Engine: Mass, Inertia and Forces

Prerequisites

Basic knowledge of linear algebra including 2D vectors and 2x2 matrices as covered in the first article in the series.

Introduction

This article intends to introduce the concepts of Local space and World space and deal with transformations from Local to World space and vice versa. It also outlines the representation of a body or physical entity in the physics engine.

Spaces

Spaces are limitless extents relative to which an object's properties, i.e. rotation and position are defined.

World Space

All objects in a world have a definite position and rotation in space, which are measured relative to the world origin. World space is omnipresent; all entities in our world will be placed relative to it.

Local Space

Local space is relative to a single entity in the world. When measured in local space of an entity, the properties of other entities are measured relative to that entity.

Transformation

Let the given point be \(X\) in world space and \(X'\) in local space relative to an entity. If the position of that entity (origin of the local space) is \(P\) and the rotation matrix of the entity (rotation matrix of the local space) is \(U = \begin{bmatrix}\cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix}\) (where \(\theta\) is the world rotation of the entity), then the following transformations can take place.

Local Space to World Space (Transform)

\(X = P + UX'\)

The local space point is first rotated to bring it to world space rotation, and then translated to the world space position.

It is important to note that a change in the local space origin or rotation will not affect a local space position. The world space position, however, may change.

World Space to Local Space (Inverse Transform)

Solving the above equation for (X') will give us the required world space to local space transformation:

\(X' = U^{-1}(X - P)\)

This gives us a problem - how to find the inverse \(U^{-1}\) of the matrix? Turns out that our rotation matrix is orthongonal, so \(U^{-1} = U^T\), where \(U^T\) is the transpose of matrix which we already know how to compute. The equation can now be rewritten as

\(X' = U^T(X - P)\)

Space transformations will be used throughout the engine to simplify mathematical routines.

Bodies

Bodies or entities are are simply objects in a world. In our case, a body is an object that can physically interact with the environment (or not, depending on its configuration). Each body has a few defining characteristics or properties, like position, velocity, torque, its shape, and mass.

A body in a physics engine does not do much by itself. Generally, all it is responsible for is integrating and updating its forces, velocities, and positions. It is the physics engine - or other external code - that manages interactions like collisions. A body will typically be manipulated by applying forces on it. However, in rare cases (like impulse collision resolution, which we will cover later), the velocity will be modified directly by the physics engine.

Body-Physics Engine Interactions

Typical interactions of a physics engine with the bodies in a world include:

  • Application of forces
  • Collision detection and resolution
  • Spatial queries (raycasts and shapecasts)
  • Joints and constraints

A Body in Code

A Body structure in Rust (taken from the engine I am building in Rust alongside this article series) looks like the following:

C++
pub struct Body {
    pub position: Vec2,
    pub rotation: f32,
    
    pub velocity: Vec2,
    pub angular_vel: f32,
    
    force: Vec2,
    torque: f32,
    
    pub mass: f32,
    pub inertia: f32,

    pub coeff_friction: f32,
    pub coeff_restitution: f32,

    pub shape: Shape,
}

This Body definition, however, is not complete. As the physics engine grows, more properties will be added to it.

History

7 Nov 2017: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)