|
Pico Headers
|
Separating Axis Theorem (SAT) Tests written in C99. More...
#include "pico_math.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_ray_t |
| A ray (directed line segment) More... | |
| struct | ph_manifold_t |
| A collision manifold Provides information about a collision. Normals always point from shape 1 to shape 2. More... | |
| struct | ph_raycast_t |
| Raycast information. More... | |
Macros | |
| #define | PICO_HIT_MAX_POLY_VERTS 16 |
Functions | |
| ph_circle_t | ph_make_circle (pv2 pos, pfloat radius) |
| Initializes a circle. | |
| ph_poly_t | ph_make_poly (const pv2 vertices[], int vertex_count) |
| Initializes a polygon. | |
| ph_ray_t | ph_make_ray (pv2 pos, pv2 dir, pfloat dist) |
| Constructs a ray. | |
| ph_poly_t | ph_aabb_to_poly (const pb2 *aabb) |
| Converts and 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_manifold_t *manifold) |
| Tests to see if one polygon overlaps with another. | |
| bool | ph_sat_poly_circle (const ph_poly_t *poly, const ph_circle_t *circle, ph_manifold_t *manifold) |
| Tests to see if a polygon overlaps a circle. | |
| bool | ph_sat_circle_poly (const ph_circle_t *circle, const ph_poly_t *poly, ph_manifold_t *manifold) |
| 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_manifold_t *manifold) |
| Tests to see if two circles overlap. | |
| 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. | |
Separating Axis Theorem (SAT) Tests written in C99.
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.
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.
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).
| #define PICO_HIT_MAX_POLY_VERTS 16 |
| ph_circle_t ph_make_circle | ( | pv2 | pos, |
| pfloat | radius | ||
| ) |
Initializes a circle.
| pos | Circle center |
| radius | Circle radius |
Initializes a polygon.
| vertex_count | The number of vertices of the polygon |
| vertices | The vertices of the polygon (must use CCW winding) |
Constructs a ray.
| pos | The origin of the array |
| dir | The direction of the ray |
| dist | The length of the ray |
Converts and axis-aligned bounding box (AABB) to a polygon.
aabb The AABB
| bool ph_sat_poly_poly | ( | const ph_poly_t * | poly_a, |
| const ph_poly_t * | poly_b, | ||
| ph_manifold_t * | manifold | ||
| ) |
Tests to see if one polygon overlaps with another.
| poly_a | The colliding polygon |
| poly_b | The target polygon |
| manifold | The collision manifold to populate (or NULL) |
| bool ph_sat_poly_circle | ( | const ph_poly_t * | poly, |
| const ph_circle_t * | circle, | ||
| ph_manifold_t * | manifold | ||
| ) |
Tests to see if a polygon overlaps a circle.
| poly | The colliding polygon |
| circle | The target circle |
| manifold | The collision manifold to populate (or NULL) |
| bool ph_sat_circle_poly | ( | const ph_circle_t * | circle, |
| const ph_poly_t * | poly, | ||
| ph_manifold_t * | manifold | ||
| ) |
Tests to see if a circle overlaps a polygon.
| circle | The colliding circle |
| poly | The target polygon |
| manifold | The collision manifold to populate (or NULL) |
| bool ph_sat_circle_circle | ( | const ph_circle_t * | circle_a, |
| const ph_circle_t * | circle_b, | ||
| ph_manifold_t * | manifold | ||
| ) |
Tests to see if two circles overlap.
| circle_a | The colliding circle |
| circle_b | The target circle |
| manifold | The collision manifold to populate (or NULL) |
| 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.
| ray | Ray to test |
| s1 | First endpoint of segment |
| s2 | Second endpoint of segment |
| raycast | Normal and distance of impact (or NULL) |
| bool ph_ray_poly | ( | const ph_ray_t * | ray, |
| const ph_poly_t * | poly, | ||
| ph_raycast_t * | raycast | ||
| ) |
Tests if ray intersects a polygon.
| ray | Ray to test |
| poly | The polygon |
| raycast | Normal and distance of impact (or NULL). May terminate early if NULL |
| bool ph_ray_circle | ( | const ph_ray_t * | ray, |
| const ph_circle_t * | circle, | ||
| ph_raycast_t * | raycast | ||
| ) |
Tests if ray intersects a circle.
| ray | Ray to test |
| circle | The circle |
| raycast | Normal and distance of impact (if not NULL). |
Finds the point along the ray at the specified distance from the origin.
Transforms a polygon using an affine transform.
| transform | The transform |
| poly | The polygon to transform |
| ph_circle_t ph_transform_circle | ( | const pt2 * | transform, |
| const ph_circle_t * | circle | ||
| ) |
Transforms a circle using an affine transform.
| transform | The transform |
| poly | The circle to transform |
| pb2 ph_circle_to_aabb | ( | const ph_circle_t * | circle | ) |
Returns the bounding box for the given circle.