Pico Libraries
Classes | Macros | Typedefs | Functions
pico_math.h File Reference

A 2D math library for games. More...

#include <float.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
Include dependency graph for pico_math.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  pv2
 A 2D vector. More...
 
struct  pt2
 A 2D transform. More...
 
struct  pb2
 A 2D axis-aligned-bounding-box (AABB) More...
 
struct  prng_t
 The pseudo random number generator (RNG) state. More...
 

Macros

#define PM_INLINE
 
#define PM_EPSILON   1e-5f
 
#define PM_PI   3.14159265359f
 
#define PM_PI2   (2.0f * PM_PI)
 
#define PM_E   2.71828182845f
 
#define PM_FLOAT_MIN   FLT_MIN
 
#define PM_FLOAT_MAX   FLT_MAX
 
#define pf_sqrt   sqrtf
 
#define pf_cos   cosf
 
#define pf_sin   sinf
 
#define pf_acos   acosf
 
#define pf_asin   asinf
 
#define pf_atan2   atan2f
 
#define pf_abs   fabsf
 
#define pf_fmod   fmodf
 
#define pf_exp   expf
 
#define pf_pow   powf
 
#define pf_floor   floorf
 
#define pf_ceil   ceilf
 
#define pf_log2   log2f
 
#define pf_max   fmaxf
 
#define pf_min   fminf
 
#define pv2_make(x, y)   ((const pv2){ x, y })
 Constructs a vector. More...
 
#define pt2_make(t00, t01, tx, t10, t11, ty)   ((const pt2){ t00, t10, t01, t11, tx, ty })
 Constructs a 2D transform. More...
 
#define pb2_make_minmax(min, max)   ((const pb2){ min, max })
 
#define pb2_make(x, y, w, h)   ((const pb2){ { x, y }, { x + w, y + h } })
 Constructs a 2D box (rectangle) More...
 

Typedefs

typedef float pfloat
 A single precision floating point number. More...
 
typedef struct prng_t prng_t
 The pseudo random number generator (RNG) state. More...
 

Functions

PM_INLINE pfloat pf_clamp (pfloat val, pfloat min, pfloat max)
 Clamps the value to the given range. More...
 
PM_INLINE pfloat pf_sign (pfloat val)
 Computes the sign of the number. More...
 
PM_INLINE bool pf_equal (pfloat c1, pfloat c2)
 Returns true if the values are within epsilon of one another. More...
 
PM_INLINE pfloat pf_lerp (pfloat a, pfloat b, pfloat alpha)
 Linearly interpolates the two values. More...
 
pfloat pf_lerp_angle (pfloat angle1, pfloat angle2, pfloat alpha)
 Linearly interpolates between two angles. More...
 
PM_INLINE pfloat pf_normalize_angle (pfloat angle)
 Clamps the angle to be in [0, 2 * PI]. More...
 
PM_INLINE bool pv2_equal (pv2 v1, pv2 v2)
 Returns true if the vectors are equal (within epsilon) More...
 
PM_INLINE pv2 pv2_add (pv2 v1, pv2 v2)
 Adds two vectors. More...
 
PM_INLINE pv2 pv2_sub (pv2 v1, pv2 v2)
 Subtracts two vectors. More...
 
PM_INLINE pv2 pv2_scale (pv2 v, pfloat c)
 Scales a vector. More...
 
PM_INLINE pfloat pv2_dot (pv2 v1, pv2 v2)
 Dot product. More...
 
PM_INLINE pfloat pv2_len2 (pv2 v)
 Returns the square of the length of the vector. More...
 
PM_INLINE pfloat pv2_len (pv2 v)
 Returns the length of the vector. More...
 
PM_INLINE pv2 pv2_normalize (pv2 v)
 Normalizes a vector (sets its length to one) More...
 
PM_INLINE pv2 pv2_reflect (pv2 v)
 Negates a vector (scales it by -1.0) More...
 
PM_INLINE pv2 pv2_perp (pv2 v)
 Construct a vector that is perpendicular to the specified vector. More...
 
PM_INLINE pfloat pv2_cross (pv2 v1, pv2 v2)
 A 2D analog of the 3D cross product. More...
 
PM_INLINE pfloat pv2_angle (pv2 v)
 Returns the angle the vector with respect to the current basis. More...
 
PM_INLINE pv2 pv2_proj (pv2 v1, pv2 v2)
 Projects a vector onto another. More...
 
PM_INLINE pfloat pv2_dist (pv2 v1, pv2 v2)
 Returns the distance between the two vectors. More...
 
PM_INLINE pv2 pv2_lerp (pv2 v1, pv2 v2, pfloat alpha)
 Linearly interpolates between two vectors. More...
 
PM_INLINE pv2 pv2_zero (void)
 Returns the zero vector. More...
 
PM_INLINE pv2 pv2_polar (pfloat angle, pfloat len)
 Contructs a vector in polar coordinates. More...
 
PM_INLINE pv2 pv2_min (pv2 v1, pv2 v2)
 Computes the component-wise minimum of two vectors. More...
 
PM_INLINE pv2 pv2_max (pv2 v1, pv2 v2)
 Computes the component-wise maximum of two vectors. More...
 
PM_INLINE pv2 pv2_floor (pv2 v)
 Computes the component-wise floor of the specified vector. More...
 
PM_INLINE pv2 pv2_ceil (pv2 v)
 Computes the component-wise ceiling of the specified vector. More...
 
PM_INLINE pt2 pt2_identity (void)
 Return the identity transform. More...
 
bool pt2_equal (const pt2 *t1, const pt2 *t2)
 Returns true if the transforms are equal (within epsilon) More...
 
PM_INLINE pv2 pt2_get_pos (const pt2 *t)
 Gets the translation components of the transform. More...
 
PM_INLINE void pt2_set_pos (pt2 *t, pv2 pos)
 Sets the translation components of the transform. More...
 
PM_INLINE pfloat pt2_get_angle (const pt2 *t)
 Gets the angle of rotation of the transform. More...
 
void pt2_set_scale (pt2 *t, pv2 scale)
 Sets the scale of the transform. More...
 
pv2 pt2_get_scale (const pt2 *t)
 Gets the scale of the transform. More...
 
void pt2_set_angle (pt2 *t, pfloat angle)
 Sets the angle of the transform. More...
 
PM_INLINE pv2 pt2_map (const pt2 *t, pv2 v)
 Transforms a vector. More...
 
PM_INLINE pfloat pt2_det (const pt2 *t)
 Returns the determinant of the transform. More...
 
pt2 pt2_inv (const pt2 *t)
 Calculates the inverse of the transform. More...
 
pt2 pt2_mult (const pt2 *t1, const pt2 *t2)
 Composes two transformations. More...
 
pt2 pt2_lerp (const pt2 *t1, const pt2 *t2, pfloat alpha)
 Linearly interpolates two transforms. More...
 
PM_INLINE pt2 pt2_scaling (pv2 scale)
 Constructs a scaling transform. More...
 
PM_INLINE pt2 pt2_rotation (pfloat angle)
 Constructs a rotation transform. More...
 
PM_INLINE pt2 pt2_translation (pv2 pos)
 Constructs a translation transform. More...
 
PM_INLINE void pt2_scale (pt2 *t, pv2 scale)
 Scales a transform. More...
 
PM_INLINE void pt2_rotate (pt2 *t, pfloat angle)
 Applies a rotation to a transform. More...
 
PM_INLINE void pt2_translate (pt2 *t, pv2 pos)
 Applies a translation a transform. More...
 
PM_INLINE pb2 pb2_zero (void)
 Returns an AABB that has zero size and coordinates. More...
 
PM_INLINE pv2 pb2_get_pos (const pb2 *b)
 Returns the position of an AABB. More...
 
PM_INLINE pv2 pb2_get_size (const pb2 *b)
 Returns the dimensions of an AABB. More...
 
PM_INLINE void pb2_set_pos (pb2 *b, pv2 pos)
 Sets the position of an AABB. More...
 
PM_INLINE void pb2_set_size (pb2 *b, pv2 size)
 Sets the dimensions of an AABB. More...
 
bool pb2_equal (const pb2 *b1, const pb2 *b2)
 Returns true if the bounding boxes are equal (within epsilon) More...
 
pb2 pb2_combine (const pb2 *b1, const pb2 *b2)
 Computes the union of b1 and `b2. More...
 
pb2 pb2_overlap (const pb2 *b1, const pb2 *b2)
 Computes the intersection of b1 and b2 More...
 
PM_INLINE bool pb2_overlaps (const pb2 *b1, const pb2 *b2)
 Return true if the two bounding boxes intersect. More...
 
PM_INLINE bool pb2_contains (const pb2 *b1, const pb2 *b2)
 Returns true if the first box is contained within the second. More...
 
PM_INLINE bool pb2_contains_point (const pb2 *b, pv2 v)
 Returns true if the box contains the point v More...
 
PM_INLINE pfloat pb2_area (const pb2 *b)
 Returns the area of the box. More...
 
PM_INLINE pv2 pb2_center (const pb2 *b)
 Computes the center of the box. More...
 
pb2 pb2_enclosing (const pv2 verts[], int count)
 Computes the minimum box containing all of the vertices. More...
 
pb2 pb2_transform (const pt2 *t, const pb2 *b)
 Computes the minimum AABB obtained by transforming the vertices of the specified AABB. More...
 
void prng_seed (prng_t *rng, uint64_t seed)
 Initialize and seed the RNG. More...
 
uint32_t prng_random (prng_t *rng)
 Generates a pseudo random number in [0, UINT32_MAX]. More...
 
pfloat pf_random (prng_t *rng)
 Generates a psuedo random number in [0, 1]. More...
 

Detailed Description

A 2D math library for games.


Licensing information at end of header

Notice:

This library has undergone a major revision with release 2.0. Although the functionality is more or less the same, the naming conventions differ substantially. To summarize, 'pm_v2', 'pm_t2', and 'pm_b2' have all been replaced by 'pv2', 'pt2', and 'pb2'. These changes affect both type defintions as well as function names. With scalar functions 'pm_' has been replaced by 'pf_', for example 'pm_equal' is now 'pf_equal'. The type 'pm_float' has been replaced by 'pfloat'. The purpose of these changes is largely to make type and function names more specific and compact. The old (and no longer maintained) version can be found at https://github.com/empyreanx/pico_headers_deprecated

Features:

Summary:

This library provides functions that act on three 2D types: vectors (pv2), transforms (pt2), and axis-align bounding boxes (pb2). The library also provides some scalar functions as well as a random number generator.

This library aims to strike a balance between performance and simplicity. Most functions return by value. All vectors are passed by value. Otherwise, transforms and AABBs are passed by pointer. There is no dynamic memory allocation.

Vector functions comprise basic vector creation and manipulation, as well as computing lengths, dot products, projections, and more.

Transformation functions include functions for computing multiplications, determinants, inverses, as well as extracting and inserting transformation parameters. There are also functions for applying rotations, scaling, and translations to a given transform. The provided functions are sufficient for implementing a scene graph.

This library provides linear interpolation for transforms, vectors, and scalars. Interpolating transforms can be used in a variety of contexts, for example, interpolated rendering when using a fixed timestep, or smoothing when performing networked physics.

Bounding box functions provide tests for intersection of AABBs and determnining if a point is contained within a given AABB. There are functions for computing unions and intersections of AABBs as well as for computing the minimum enclosing AABB for a set of points.

The random number generator uses the xoshiro128** algorithm, which is substantially better than rand() in terms of the quality of its output without sacrificing too much performance.

Please see the unit tests for some concrete examples.

Usage:

To use this library in your project, add the following

#define PICO_MATH_IMPLEMENTATION #include "pico_ml.h"

to a source file (once), then simply include the header normally.

Macro Definition Documentation

◆ PM_INLINE

#define PM_INLINE

◆ PM_EPSILON

#define PM_EPSILON   1e-5f

◆ PM_PI

#define PM_PI   3.14159265359f

◆ PM_PI2

#define PM_PI2   (2.0f * PM_PI)

◆ PM_E

#define PM_E   2.71828182845f

◆ PM_FLOAT_MIN

#define PM_FLOAT_MIN   FLT_MIN

◆ PM_FLOAT_MAX

#define PM_FLOAT_MAX   FLT_MAX

◆ pf_sqrt

#define pf_sqrt   sqrtf

◆ pf_cos

#define pf_cos   cosf

◆ pf_sin

#define pf_sin   sinf

◆ pf_acos

#define pf_acos   acosf

◆ pf_asin

#define pf_asin   asinf

◆ pf_atan2

#define pf_atan2   atan2f

◆ pf_abs

#define pf_abs   fabsf

◆ pf_fmod

#define pf_fmod   fmodf

◆ pf_exp

#define pf_exp   expf

◆ pf_pow

#define pf_pow   powf

◆ pf_floor

#define pf_floor   floorf

◆ pf_ceil

#define pf_ceil   ceilf

◆ pf_log2

#define pf_log2   log2f

◆ pf_max

#define pf_max   fmaxf

◆ pf_min

#define pf_min   fminf

◆ pv2_make

#define pv2_make (   x,
 
)    ((const pv2){ x, y })

Constructs a vector.

◆ pt2_make

#define pt2_make (   t00,
  t01,
  tx,
  t10,
  t11,
  ty 
)    ((const pt2){ t00, t10, t01, t11, tx, ty })

Constructs a 2D transform.

◆ pb2_make_minmax

#define pb2_make_minmax (   min,
  max 
)    ((const pb2){ min, max })

◆ pb2_make

#define pb2_make (   x,
  y,
  w,
 
)    ((const pb2){ { x, y }, { x + w, y + h } })

Constructs a 2D box (rectangle)

Typedef Documentation

◆ pfloat

typedef float pfloat

A single precision floating point number.

◆ prng_t

typedef struct prng_t prng_t

The pseudo random number generator (RNG) state.

Function Documentation

◆ pf_clamp()

PM_INLINE pfloat pf_clamp ( pfloat  val,
pfloat  min,
pfloat  max 
)

Clamps the value to the given range.

◆ pf_sign()

PM_INLINE pfloat pf_sign ( pfloat  val)

Computes the sign of the number.

Returns
: -1 if val is less than zero 0 if val is equal to zero 1 if val is greater than zero

◆ pf_equal()

PM_INLINE bool pf_equal ( pfloat  c1,
pfloat  c2 
)

Returns true if the values are within epsilon of one another.

◆ pf_lerp()

PM_INLINE pfloat pf_lerp ( pfloat  a,
pfloat  b,
pfloat  alpha 
)

Linearly interpolates the two values.

Parameters
aOne endpoint
bAnother endpoint
alphaA number in [0, 1] that specifies the position between the endpoints

◆ pf_lerp_angle()

pfloat pf_lerp_angle ( pfloat  angle1,
pfloat  angle2,
pfloat  alpha 
)

Linearly interpolates between two angles.

Parameters
angle1The first endpoint
angle2The second endpoint
alphaThe normalized distance between angle1 and angle2

◆ pf_normalize_angle()

PM_INLINE pfloat pf_normalize_angle ( pfloat  angle)

Clamps the angle to be in [0, 2 * PI].

◆ pv2_equal()

PM_INLINE bool pv2_equal ( pv2  v1,
pv2  v2 
)

Returns true if the vectors are equal (within epsilon)

◆ pv2_add()

PM_INLINE pv2 pv2_add ( pv2  v1,
pv2  v2 
)

Adds two vectors.

Parameters
v1First vector
v2Second vector

◆ pv2_sub()

PM_INLINE pv2 pv2_sub ( pv2  v1,
pv2  v2 
)

Subtracts two vectors.

Parameters
v1First vector
v2Second vector

◆ pv2_scale()

PM_INLINE pv2 pv2_scale ( pv2  v,
pfloat  c 
)

Scales a vector.

Parameters
vVector to scale
cThe scale factor

◆ pv2_dot()

PM_INLINE pfloat pv2_dot ( pv2  v1,
pv2  v2 
)

Dot product.

◆ pv2_len2()

PM_INLINE pfloat pv2_len2 ( pv2  v)

Returns the square of the length of the vector.

◆ pv2_len()

PM_INLINE pfloat pv2_len ( pv2  v)

Returns the length of the vector.

◆ pv2_normalize()

PM_INLINE pv2 pv2_normalize ( pv2  v)

Normalizes a vector (sets its length to one)

Parameters
vThe vector to normalize
Returns
The normalized vector

◆ pv2_reflect()

PM_INLINE pv2 pv2_reflect ( pv2  v)

Negates a vector (scales it by -1.0)

Parameters
vThe vector to negate
Returns
The negated vecotor

◆ pv2_perp()

PM_INLINE pv2 pv2_perp ( pv2  v)

Construct a vector that is perpendicular to the specified vector.

Parameters
vThe vector to be made perpendicular
Returns
The perpendicular vector

◆ pv2_cross()

PM_INLINE pfloat pv2_cross ( pv2  v1,
pv2  v2 
)

A 2D analog of the 3D cross product.

◆ pv2_angle()

PM_INLINE pfloat pv2_angle ( pv2  v)

Returns the angle the vector with respect to the current basis.

◆ pv2_proj()

PM_INLINE pv2 pv2_proj ( pv2  v1,
pv2  v2 
)

Projects a vector onto another.

Parameters
v1The vector to be projected
v2The vector to project onto
Returns
The projection of v1 onto v2

◆ pv2_dist()

PM_INLINE pfloat pv2_dist ( pv2  v1,
pv2  v2 
)

Returns the distance between the two vectors.

◆ pv2_lerp()

PM_INLINE pv2 pv2_lerp ( pv2  v1,
pv2  v2,
pfloat  alpha 
)

Linearly interpolates between two vectors.

Parameters
v1The first endpoint
v2The second endpoint
alphaThe normalized distance between v1 and v2

◆ pv2_zero()

PM_INLINE pv2 pv2_zero ( void  )

Returns the zero vector.

◆ pv2_polar()

PM_INLINE pv2 pv2_polar ( pfloat  angle,
pfloat  len 
)

Contructs a vector in polar coordinates.

◆ pv2_min()

PM_INLINE pv2 pv2_min ( pv2  v1,
pv2  v2 
)

Computes the component-wise minimum of two vectors.

◆ pv2_max()

PM_INLINE pv2 pv2_max ( pv2  v1,
pv2  v2 
)

Computes the component-wise maximum of two vectors.

◆ pv2_floor()

PM_INLINE pv2 pv2_floor ( pv2  v)

Computes the component-wise floor of the specified vector.

◆ pv2_ceil()

PM_INLINE pv2 pv2_ceil ( pv2  v)

Computes the component-wise ceiling of the specified vector.

◆ pt2_identity()

PM_INLINE pt2 pt2_identity ( void  )

Return the identity transform.

◆ pt2_equal()

bool pt2_equal ( const pt2 t1,
const pt2 t2 
)

Returns true if the transforms are equal (within epsilon)

◆ pt2_get_pos()

PM_INLINE pv2 pt2_get_pos ( const pt2 t)

Gets the translation components of the transform.

Parameters
tPointer to the transform

◆ pt2_set_pos()

PM_INLINE void pt2_set_pos ( pt2 t,
pv2  pos 
)

Sets the translation components of the transform.

Parameters
tPointer to the transform
posThe position vector

◆ pt2_get_angle()

PM_INLINE pfloat pt2_get_angle ( const pt2 t)

Gets the angle of rotation of the transform.

◆ pt2_set_scale()

void pt2_set_scale ( pt2 t,
pv2  scale 
)

Sets the scale of the transform.

Scalings are now assumed to be pre-multiplied. This change was made because the common case is usually a tranlation to the origin, followed by scaling, then a rotation and finally, another translation.

Parameters
tThe transform
scaleThe vector containing scale factors in the x/y directions

◆ pt2_get_scale()

pv2 pt2_get_scale ( const pt2 t)

Gets the scale of the transform.

Scalings are now assumed to be pre-multiplied. This change was made because the common case is usually a tranlation to the origin, followed by scaling, then a rotation and finally, another translation.

Parameters
tThe transform

◆ pt2_set_angle()

void pt2_set_angle ( pt2 t,
pfloat  angle 
)

Sets the angle of the transform.

◆ pt2_map()

PM_INLINE pv2 pt2_map ( const pt2 t,
pv2  v 
)

Transforms a vector.

Parameters
tThe transform
vThe vector to be transformed

◆ pt2_det()

PM_INLINE pfloat pt2_det ( const pt2 t)

Returns the determinant of the transform.

◆ pt2_inv()

pt2 pt2_inv ( const pt2 t)

Calculates the inverse of the transform.

Parameters
tThe transform to invert

◆ pt2_mult()

pt2 pt2_mult ( const pt2 t1,
const pt2 t2 
)

Composes two transformations.

◆ pt2_lerp()

pt2 pt2_lerp ( const pt2 t1,
const pt2 t2,
pfloat  alpha 
)

Linearly interpolates two transforms.

◆ pt2_scaling()

PM_INLINE pt2 pt2_scaling ( pv2  scale)

Constructs a scaling transform.

Parameters
scaleThe scaling components

◆ pt2_rotation()

PM_INLINE pt2 pt2_rotation ( pfloat  angle)

Constructs a rotation transform.

Parameters
angleThe angle of rotation

◆ pt2_translation()

PM_INLINE pt2 pt2_translation ( pv2  pos)

Constructs a translation transform.

Parameters
posThe translation coordinates

◆ pt2_scale()

PM_INLINE void pt2_scale ( pt2 t,
pv2  scale 
)

Scales a transform.

Parameters
tThe transform to scale
scaleThe scaling parameters

◆ pt2_rotate()

PM_INLINE void pt2_rotate ( pt2 t,
pfloat  angle 
)

Applies a rotation to a transform.

Parameters
tThe transform to rotate
angleThe angle to rotate by

◆ pt2_translate()

PM_INLINE void pt2_translate ( pt2 t,
pv2  pos 
)

Applies a translation a transform.

Parameters
tThe transform to translate
posThe translation components

◆ pb2_zero()

PM_INLINE pb2 pb2_zero ( void  )

Returns an AABB that has zero size and coordinates.

◆ pb2_get_pos()

PM_INLINE pv2 pb2_get_pos ( const pb2 b)

Returns the position of an AABB.

◆ pb2_get_size()

PM_INLINE pv2 pb2_get_size ( const pb2 b)

Returns the dimensions of an AABB.

◆ pb2_set_pos()

PM_INLINE void pb2_set_pos ( pb2 b,
pv2  pos 
)

Sets the position of an AABB.

Parameters
bThe AABB
posThe new position

◆ pb2_set_size()

PM_INLINE void pb2_set_size ( pb2 b,
pv2  size 
)

Sets the dimensions of an AABB.

Parameters
bThe AABB
sizeThe new size

◆ pb2_equal()

bool pb2_equal ( const pb2 b1,
const pb2 b2 
)

Returns true if the bounding boxes are equal (within epsilon)

◆ pb2_combine()

pb2 pb2_combine ( const pb2 b1,
const pb2 b2 
)

Computes the union of b1 and `b2.

◆ pb2_overlap()

pb2 pb2_overlap ( const pb2 b1,
const pb2 b2 
)

Computes the intersection of b1 and b2

◆ pb2_overlaps()

PM_INLINE bool pb2_overlaps ( const pb2 b1,
const pb2 b2 
)

Return true if the two bounding boxes intersect.

◆ pb2_contains()

PM_INLINE bool pb2_contains ( const pb2 b1,
const pb2 b2 
)

Returns true if the first box is contained within the second.

◆ pb2_contains_point()

PM_INLINE bool pb2_contains_point ( const pb2 b,
pv2  v 
)

Returns true if the box contains the point v

◆ pb2_area()

PM_INLINE pfloat pb2_area ( const pb2 b)

Returns the area of the box.

◆ pb2_center()

PM_INLINE pv2 pb2_center ( const pb2 b)

Computes the center of the box.

◆ pb2_enclosing()

pb2 pb2_enclosing ( const pv2  verts[],
int  count 
)

Computes the minimum box containing all of the vertices.

Parameters
vertsThe vertices
countThe number of vertices

◆ pb2_transform()

pb2 pb2_transform ( const pt2 t,
const pb2 b 
)

Computes the minimum AABB obtained by transforming the vertices of the specified AABB.

◆ prng_seed()

void prng_seed ( prng_t rng,
uint64_t  seed 
)

Initialize and seed the RNG.

Parameters
rngA reference to the RNG
seedThe seed (choosing the same seed will yield identical sequences)

◆ prng_random()

uint32_t prng_random ( prng_t rng)

Generates a pseudo random number in [0, UINT32_MAX].

Parameters
rngA reference to the RNG

◆ pf_random()

pfloat pf_random ( prng_t rng)

Generates a psuedo random number in [0, 1].