Pico Headers
Loading...
Searching...
No Matches
Classes | Macros | Functions
pico_hit.h File Reference

Separating Axis Theorem (SAT) Tests written in C99. More...

#include "pico_math.h"
Include dependency graph for pico_hit.h:

Go to the source code of this file.

Classes

struct  ph_circle_t
 A circle shape. More...
 
struct  ph_poly_t
 A polygon shape Must use CCW (counter-clockwise) winding. More...
 
struct  ph_sat_t
 A collision result Provides information about a collision. Normals always point from the target shape to the colliding shape. More...
 
struct  ph_contact_t
 A contact point. More...
 
struct  ph_manifold_t
 
struct  ph_ray_t
 A ray (directed line segment) More...
 
struct  ph_raycast_t
 Raycast information. More...
 

Macros

#define PICO_HIT_MAX_POLY_VERTS   16
 

Functions

ph_circle_t ph_make_circle (pv2 center, pfloat radius)
 Initializes a circle.
 
ph_poly_t ph_make_poly (const pv2 vertices[], int count, bool reverse)
 Initializes a polygon.
 
ph_ray_t ph_make_ray (pv2 origin, pv2 dir, pfloat len)
 Constructs a ray.
 
ph_poly_t ph_aabb_to_poly (const pb2 *aabb)
 Converts an axis-aligned bounding box (AABB) to a polygon.
 
bool ph_sat_poly_poly (const ph_poly_t *poly_a, const ph_poly_t *poly_b, ph_sat_t *result)
 Tests to see if one convex polygon overlaps with another.
 
bool ph_sat_poly_circle (const ph_poly_t *poly, const ph_circle_t *circle, ph_sat_t *result)
 Tests to see if a convex polygon overlaps a circle.
 
bool ph_sat_circle_poly (const ph_circle_t *circle, const ph_poly_t *poly, ph_sat_t *result)
 Tests to see if a circle overlaps a polygon.
 
bool ph_sat_circle_circle (const ph_circle_t *circle_a, const ph_circle_t *circle_b, ph_sat_t *result)
 Tests to see if two circles overlap.
 
bool ph_manifold_poly_poly (const ph_poly_t *poly_a, const ph_poly_t *poly_b, ph_manifold_t *manifold)
 Tests if a polygon collides with another polygon and generates contact information.
 
bool ph_manifold_poly_circle (const ph_poly_t *poly, const ph_circle_t *circle, ph_manifold_t *manifold)
 Tests if a polygon and circle collide and generates contact information.
 
bool ph_manifold_circle_poly (const ph_circle_t *circle, const ph_poly_t *poly, ph_manifold_t *manifold)
 Tests if a circle and polygon collide and generates contact information.
 
bool ph_manifold_circle_circle (const ph_circle_t *circle_a, const ph_circle_t *circle_b, ph_manifold_t *manifold)
 Tests if two circles collide and generates contact information.
 
bool ph_ray_line (const ph_ray_t *ray, pv2 s1, pv2 s2, ph_raycast_t *raycast)
 Tests if ray intersects a (directed) line segment.
 
bool ph_ray_poly (const ph_ray_t *ray, const ph_poly_t *poly, ph_raycast_t *raycast)
 Tests if ray intersects a polygon.
 
bool ph_ray_circle (const ph_ray_t *ray, const ph_circle_t *circle, ph_raycast_t *raycast)
 Tests if ray intersects a circle.
 
pv2 ph_ray_at (const ph_ray_t *ray, pfloat dist)
 Finds the point along the ray at the specified distance from the origin.
 
ph_poly_t ph_transform_poly (const pt2 *transform, const ph_poly_t *poly)
 Transforms a polygon using an affine transform.
 
ph_circle_t ph_transform_circle (const pt2 *transform, const ph_circle_t *circle)
 Transforms a circle using an affine transform.
 
pb2 ph_poly_to_aabb (const ph_poly_t *poly)
 Returns the bounding box for the given polygon.
 
pb2 ph_circle_to_aabb (const ph_circle_t *circle)
 Returns the bounding box for the given circle.
 

Detailed Description

Separating Axis Theorem (SAT) Tests written in C99.


Licensing information at end of header

Features:

Summary:

The Separating Axis Theorem (SAT) roughly states that two convex shapes do not intersect if there is an axis separating them. In the case of simple shapes the theorem provides necessary and sufficient conditions. For example, in the case of convex polygons, it is sufficient to test the axises along the edge normals of both polygons.

SAT tests are reasonably efficient and are frequently used for static, narrow phase, collision detection in games.

This library provides SAT tests for polygons, AABBs (which are, of course, polygons), and circles. Manifold objects can be passed to test functions so that, in the case of a collision, they will contain the colliding edge normal, overlap (minimum translational distance or MTD), and a vector (minimum translation vector or MTV).

Rays (directed line segments) can be cast against line segments, polygons, and circles. Aside from reporting hits, the normal at and distance to the point of impact is also available.

IMPORTANT: Polygons in this library use counter-clockwise (CCW) winding. See the ph_aabb_to_poly for an example.

Usage:

To use this library in your project, add the following

‍#define PICO_HIT_IMPLEMENTATION #include "pico_hit.h"

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

Dependencies:

This library depends on "pico_math.h", which must be in the include path. You must also add

‍#define PICO_MATH_IMPLEMENTATION #include "pico_math.h"

to the same or other source file (once).

Macro Definition Documentation

◆ PICO_HIT_MAX_POLY_VERTS

#define PICO_HIT_MAX_POLY_VERTS   16

Function Documentation

◆ ph_make_circle()

ph_circle_t ph_make_circle ( pv2  center,
pfloat  radius 
)

Initializes a circle.

Parameters
centerCircle center
radiusCircle radius

◆ ph_make_poly()

ph_poly_t ph_make_poly ( const pv2  vertices[],
int  count,
bool  reverse 
)

Initializes a polygon.

Parameters
countThe number of vertices of the polygon
verticesThe vertices of the polygon
reverseConverts a polygon with CW winding to CCW
Returns
The polygon with the given vertices

◆ ph_make_ray()

ph_ray_t ph_make_ray ( pv2  origin,
pv2  dir,
pfloat  len 
)

Constructs a ray.

Parameters
posThe origin of the array
dirThe direction of the ray (normalized)
lenThe length of the ray

◆ ph_aabb_to_poly()

ph_poly_t ph_aabb_to_poly ( const pb2 aabb)

Converts an axis-aligned bounding box (AABB) to a polygon.

aabb The AABB

Returns
the AABB as a polygon

◆ ph_sat_poly_poly()

bool ph_sat_poly_poly ( const ph_poly_t poly_a,
const ph_poly_t poly_b,
ph_sat_t result 
)

Tests to see if one convex polygon overlaps with another.

Parameters
poly_aThe colliding polygon
poly_bThe target polygon
resultThe collision result to populate (or NULL)
Returns
True if the polygons overlap and false otherwise

◆ ph_sat_poly_circle()

bool ph_sat_poly_circle ( const ph_poly_t poly,
const ph_circle_t circle,
ph_sat_t result 
)

Tests to see if a convex polygon overlaps a circle.

Parameters
polyThe colliding polygon
circleThe target circle
resultThe collision result to populate (or NULL)
Returns
True if the polygon and circle overlap, and false otherwise

◆ ph_sat_circle_poly()

bool ph_sat_circle_poly ( const ph_circle_t circle,
const ph_poly_t poly,
ph_sat_t result 
)

Tests to see if a circle overlaps a polygon.

Parameters
circleThe colliding circle
polyThe target polygon
resultThe collision result to populate (or NULL)
Returns
True if the circle overlaps the polygon, and false otherwise

◆ ph_sat_circle_circle()

bool ph_sat_circle_circle ( const ph_circle_t circle_a,
const ph_circle_t circle_b,
ph_sat_t result 
)

Tests to see if two circles overlap.

Parameters
circle_aThe colliding circle
circle_bThe target circle
resultThe collision result to populate (or NULL)
Returns
True if the circle and the other circle, and false otherwise

◆ ph_manifold_poly_poly()

bool ph_manifold_poly_poly ( const ph_poly_t poly_a,
const ph_poly_t poly_b,
ph_manifold_t manifold 
)

Tests if a polygon collides with another polygon and generates contact information.

Parameters
poly_aThe colliding polygon
poly_bThe target polygon
manifoldThe contact manifold to populate
Returns
True if contacts are generated successfully, and false otherwise

◆ ph_manifold_poly_circle()

bool ph_manifold_poly_circle ( const ph_poly_t poly,
const ph_circle_t circle,
ph_manifold_t manifold 
)

Tests if a polygon and circle collide and generates contact information.

Parameters
polyThe polygon
circleThe circle
manifoldThe contact manifold to populate
Returns
True if contacts are generated successfully, and false otherwise

◆ ph_manifold_circle_poly()

bool ph_manifold_circle_poly ( const ph_circle_t circle,
const ph_poly_t poly,
ph_manifold_t manifold 
)

Tests if a circle and polygon collide and generates contact information.

Parameters
circleThe circle
polyThe polygon
manifoldThe contact manifold to populate
Returns
True if contacts are generated successfully, and false otherwise

◆ ph_manifold_circle_circle()

bool ph_manifold_circle_circle ( const ph_circle_t circle_a,
const ph_circle_t circle_b,
ph_manifold_t manifold 
)

Tests if two circles collide and generates contact information.

Parameters
circle_aFirst circle
circle_bSecond circle
manifoldThe contact manifold to populate
Returns
True if contacts are generated successfully, and false otherwise

◆ ph_ray_line()

bool ph_ray_line ( const ph_ray_t ray,
pv2  s1,
pv2  s2,
ph_raycast_t raycast 
)

Tests if ray intersects a (directed) line segment.

Parameters
rayRay to test
s1First endpoint of segment
s2Second endpoint of segment
raycastNormal and distance of impact (or NULL)
Returns
True if the ray collides with the line segment and false otherwise

◆ ph_ray_poly()

bool ph_ray_poly ( const ph_ray_t ray,
const ph_poly_t poly,
ph_raycast_t raycast 
)

Tests if ray intersects a polygon.

Parameters
rayRay to test
polyThe target polygon
raycastNormal and distance of impact (or NULL). May terminate early if NULL
Returns
True if the ray collides with the polygon and false otherwise

◆ ph_ray_circle()

bool ph_ray_circle ( const ph_ray_t ray,
const ph_circle_t circle,
ph_raycast_t raycast 
)

Tests if ray intersects a circle.

Parameters
rayRay to test
circleThe target circle
raycastNormal and distance of impact (if not NULL).
Returns
True if the ray collides with the circle and false otherwise

◆ ph_ray_at()

pv2 ph_ray_at ( const ph_ray_t ray,
pfloat  dist 
)

Finds the point along the ray at the specified distance from the origin.

◆ ph_transform_poly()

ph_poly_t ph_transform_poly ( const pt2 transform,
const ph_poly_t poly 
)

Transforms a polygon using an affine transform.

Parameters
transformThe transform
polyThe polygon to transform
Returns
A new polygon

◆ ph_transform_circle()

ph_circle_t ph_transform_circle ( const pt2 transform,
const ph_circle_t circle 
)

Transforms a circle using an affine transform.

Parameters
transformThe transform
polyThe circle to transform
Returns
A new circle

◆ ph_poly_to_aabb()

pb2 ph_poly_to_aabb ( const ph_poly_t poly)

Returns the bounding box for the given polygon.

◆ ph_circle_to_aabb()

pb2 ph_circle_to_aabb ( const ph_circle_t circle)

Returns the bounding box for the given circle.