Giter VIP home page Giter VIP logo

simplecollisions.jl's Introduction

SimpleCollisions

This package provides fast and lightweight "primitives" for 2D physics. Roughly speaking, it offers a collection of methods and structs needed to detect and resolve collisions between simple 2D shapes like circles and rectangles, along with some basic methods to calculate impulses when two rigid bodies collide with each other. The priority is high performance for the simple cases instead of adding sophisticated feature.

In order to cite this package, please refer to the file CITATION.bib. Starring the repository on GitHub is also appreciated.

Design

  1. What This Package Is NOT About
  2. Position and Orientation
  3. Shapes
    1. StandardPoint
    2. StandardLine
    3. StandardCircle
    4. StandardRect
  4. Collisions
    1. Collision Detection
    2. Collision Manifold
  5. Physics
    1. Impulse

What This Package Is NOT About

This package is not a physics engine in itself, even though it is inspired by physics engines ImpulseEngine and box2d. The reason for only providing primitives instead of a full-blown physics engine is to keep this package lightweight, make minimal or no assumptions about a game, and allow for context-specific optimizations in a game (that are often hard to generalize in advance).

This package does not provide a generalized game loop. In order to understand why this is so, consider the example of 2D collision detection. In your game loop, it may or may not be terribly inefficient to check for exact pair-wise collisions (narrow phase) for all possible pairs of rigid bodies at every iteration. And there are several possible heuristics to optimize this further (like broad phase algorithms). But, once you know the specific game you are trying to build, you get full control of the collision detection process and can choose to check only those pairs that are make sense in the context of your game. This not only allows for a fine degree of optimization, but could also be a much simpler solution overall as compared to the generalized broad-phase heuristics that may still not be good enough for your case.

Position and Orientation

A position on the 2D coordinate plane (with respect to the world origin) is represented using an instance of StaticArrays.SVector{2, T}. An orientation on the 2D coordinate plane (with respect to the world coordinate axes) can be represented compactly by a single scalar denoting the counterclockwise angle theta (in radians) with respect to the world x-axes. Equivalently, a 2D unit vector StaticArrays.SVector(cos(theta), sin(theta)) could also be used to represent a direction. This package uses the latter representation of orientation.

Computations involving orientation often require cos(theta) and sin(theta). Overall, it is cheaper to cache cos(theta)s and sin(theta)s than to repeatedly compute the trigonmetric functions from the angle theta each time.

Shapes

This package provides the following shapes: StandardPoint, StandardLine, StandardCircle, and StandardRect. Here, a standard shape refers to a shape whose geometric center is placed at the world origin and whose orientation (as determined by some form of symmetry) is aligned with the positive world x-axis. We use Standard shapes to decouple the shape of a body from its position and orientation with respect to the world frame of reference. A Standard shape can be passed along with a position and (optionally) an orientation to represent a body of that shape at an arbitrary location and orientation with respect to the world frame of reference.

StandardPoint

struct StandardPoint{T} <: AbstractShape end

StandardPoint is a point placed at the origin. It doesn't require any fields.

StandardLine

struct StandardLine{T} <: AbstractShape
    half_length::T
end

StandardLine is a line segment centered at the origin and aligned with the world x-axes. It requires only one field - a half_length.

StandardCircle

struct StandardCircle{T} <: AbstractShape
    radius::T
end

StandardCirle is a circle centered at the origin. It requires only one field - a radius.

StandardRect

struct StandardRect{T} <: AbstractShape
    half_width::T
    half_height::T
end

StandardRect is a rectangle centered at the origin with its edges parallel to the world coordinate axes (width edges parallel to world x-axis and height edges parallel to world y-axis). It requires two fields - a half_width and a half_height.

Collisions

Collision Detection

This package offers the is_colliding function to detect collisions between pairs of bodies with Standard shapes at arbitrary relative positions and orientations. If the orientation of both the bodies are aligned with world x-axis (for example, collision detection between two axes-aligned bounding boxes), that is, the bodies are just shifted versions of Standard shapes, or even if their orientations only mutually align, then do not pass the relative orientation argument to the is_colliding function and you will dispatch to faster method.

The position and orientation arguments (whenever present) in the is_colliding method definitinos refer to the relative position and orientation of the second body (second argument) in the frame of reference of the first body (first argument). The decoupling of the shapes of the bodies shapes from their positions and orientations allows us to exploit symmetry and speed up the computation for collision detection and manifold generation for certain common use cases (for example, in the case of collision of two axes-aligned bounding boxes, where you would not pass the relative orientation argument to is_colliding function). We use relative positions and orientations instead of absolute ones in order to make the geometry calculations easier to understand. I don't think frame of reference conversions required for this have any significant computational overhead. Calculating relative positions is just subtracting two vectors, and calculating relative orientation is pretty cheap too because we already cache sin(theta) and cos(theta) in the unit vectors.

Collision Manifold

A collision manifold contains information about how to resolve a collision once it has been detected. The following is the struct used to represent a collision manifold:

struct Manifold{T}
    penetration::T
    normal::Vector2D{T}
    contact::Vector2D{T}
end

Here the normal field corresponds to the collision normal. A Manifold object is calculated with respect to the frame of reference of the first body (first argument). It is important to note that manifold generation for a collision assumes (wherever needed) that the two objects are indeed colliding.

Physics

This package does not provide a concrete type representing a generalized rigid body. Some rigid bodies may be static (may not require any mass or velocity related fields), some may be kinetic (may not require mass related fields), some may be dynamic (may require a lot of fields), some may not rotate at all (may not require any orientation related fields), some may be frictionless (may not require static or kinematic friction coefficients) etc... Basically, there is a lot of variety out there, and trying to make an optimized decision upfront is very difficult, if not impossible. Storing all such potential fields into one rigid body struct would often lead to wasteful memory and computations.

This package provides the following functions to calculate the linear impulse of two colliding rigid bodies:

  1. get_normal_impulse: calcuates the normal impulse for a collisions
  2. get_tangential_impulse: calcuates the tangential impulse (caused by friction) for a collision

simplecollisions.jl's People

Contributors

sid-bhatia-0 avatar

Stargazers

ebigram avatar  avatar  avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.