coll

package module
v1.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2025 License: MIT Imports: 4 Imported by: 0

Image README

GoDoc

coll - 2d collision library for Go

Features

  • Collisions only - no gravity, rigid body handling, or complex solvers
  • Is data-oriented and functional

Conventions

"Sweep" tests indicate at least 1 of the objects is moving. The number indicates how many objects are moving. e.g., box-box-sweep2 means we are comparing 2 aabbs, both of which are moving. "Overlap" tests don't take movement into account, and this is a static check to see if the 2 entities overlap. plural forms imply a collection. e.g., BoxSegmentsSweep1Indexed() checks one box segment against a set of line segments. If there is more than one collision, the closest collision is set in the h *Hit argument.

Visualization of some (but not all) functions

Box-Box overlap

Box-Box-overlap

Box-Box sweep 1

Box-Box sweep 1

Box-Box sweep 2

Box-Box sweep 2

Box-OrientedBox overlap

abb-obb-overlap

Box-Segment sweep 1

Box-Segment sweep 1

Box-Segments sweep 1 indexed

Box-Segments sweep 1

Box-Segment overlap

Box-Segment overlap

Line-Circle overlap

alt text

Segment-Circle overlap

alt text

Examples (Ebitengine)

  1. Clone this repository
  2. In the terminal, change to the examples directory cd examples
  3. Run a folder with go run ./foldername. Example: go run ./box_box_sweep1

Credits

Most of these collision checks were adapted from existing open source repos:

Image Documentation

Overview

2D Collision functions

Index

Constants

View Source
const (
	Epsilon float64 = 1e-8
	Padding float64 = 0.005
)

Variables

This section is empty.

Functions

func BoxBoxContain added in v1.4.0

func BoxBoxContain(a, b *AABB) bool

BoxBoxContain returns true if a fully contains b (b is fully inside of the bounds of a).

func BoxBoxOverlap added in v1.4.0

func BoxBoxOverlap(a, b *AABB, h *Hit) bool

BoxBoxOverlap checks whether a and b overlap.

If h is not nil, the function fills it with for box b:

  • Normal: Collision surface normal for box b
  • Data: the penetration depth for box b (overlap distance)

This method can behave poorly for moving objects.

For continuous motion, BoxBoxSweep1() of BoxBoxSweep2() should be used instead.

func BoxBoxSweep1 added in v1.4.0

func BoxBoxSweep1(staticA, dynamicB *AABB, deltaB v.Vec, h *Hit) bool

BoxBoxSweep1 Returns true if collision occurs during movement. Fills hit info h for dynamicB if not nil.

func BoxBoxSweep2 added in v1.4.0

func BoxBoxSweep2(a, b *AABB, deltaA, deltaB v.Vec, h *Hit) bool

BoxBoxSweep2 Returns true if collision occurs during movement. Fills hit info h for b if not nil.

func BoxCircleOverlap added in v1.4.0

func BoxCircleOverlap(a *AABB, c *Circle, h *Hit) bool

BoxCircleOverlap checks whether box and circle overlap.

If h is not nil, the function fills it with:

  • Normal: the surface normal of box
  • Data: penetration depth (distance to move the box)

To resolve the overlap:

newBoxPos = box.Pos.Add(hit.Normal.Neg().Scale(hit.Data))

func BoxCircleSweep2 added in v1.4.0

func BoxCircleSweep2(a *AABB, b *Circle, deltaA, deltaB v.Vec, h *Hit) bool

BoxCircleSweep2 checks for collision between a moving AABB and a moving Circle.

Returns true if collision occurs during movement, false otherwise.

func BoxOrientedBoxOverlap added in v1.4.6

func BoxOrientedBoxOverlap(a *AABB, o *OBB) bool

BoxOrientedBoxOverlap tests if an AABB and OBB are currently intersecting. For moving objects, use BoxOrientedBoxSweep2 to prevent tunneling.

func BoxOrientedBoxSweep2 added in v1.4.6

func BoxOrientedBoxSweep2(a *AABB, o *OBB, deltaA v.Vec, deltaO v.Vec) bool

BoxOrientedBoxSweep2 tests if a moving AABB and moving OBB intersect during their motion. Uses swept volume testing to prevent tunneling for fast-moving objects.

func BoxPointOverlap added in v1.4.0

func BoxPointOverlap(box *AABB, point v.Vec, h *Hit) bool

BoxPointOverlap returns true if the point is in the box, false otherwise. If h is not nil, the function fills it with for point:

  • Normal: Collision surface normal for box
  • Data: the penetration depth for point

func BoxSegmentOverlap added in v1.4.0

func BoxSegmentOverlap(box *AABB, start, delta, padding v.Vec, h *Hit) bool

BoxSegmentOverlap returns true if they intersect, false otherwise.

Params:

  • box - Bounding box to check
  • start - Ray segment origin/start position
  • delta - Ray segment move/displacement vector
  • padding - Padding added to the radius of the bounding box
  • h - Contact info for segment. Filled when argument isn't nil and a collision occurs

func BoxSegmentSweep1 added in v1.4.0

func BoxSegmentSweep1(s *Segment, a *AABB, deltaA v.Vec, h *Hit) bool

BoxSegmentSweep1 sweep a moving box against a static line segment.

If h is not nil and a collision is detected, it will be populated with:

  • Normal: Collision surface normal for the box
  • Data: Normalized time of impact (0.0 to 1.0) along the movement path

func BoxSegmentsSweep1Indexed added in v1.4.3

func BoxSegmentsSweep1Indexed(s []*Segment, a *AABB, deltaA v.Vec, h *Hit) (index int)

BoxSegmentsSweep1Indexed returns the index of the colliding segment, or -1 if no collision was detected.

Performs a sweep test of an box against a slice of segments.

To determine the earliest point of impact along a movement vector, It iterates through the provided segments and finds the collision that occurs at the minimum time value. If h is not nil and a collision is detected, it will be populated with:

  • Normal: Collision surface normal for the box
  • Data: Normalized time of impact (0.0 to 1.0) along the movement path

func CircleCircleSweep2 added in v1.4.7

func CircleCircleSweep2(c1, c2 *Circle, deltaC1, deltaC2 v.Vec, h *Hit) bool

CircleCircleSweep2 checks for collision between two moving circles to prevent tunneling.

Returns true if collision occurs during movement or if they are already overlapping.

If h is not nil and a collision is detected, it will be populated with:

  • Normal: Collision surface normal for c2
  • Data: Normalized time of impact (0.0 to 1.0) along the movement path

func LineCircleOverlap added in v1.4.0

func LineCircleOverlap(raySeg *Segment, c *Circle, result *Segment) bool

LineCircleOverlap checks if the infinite line defined by the given raySeg intersects with a circle. Return true if the infinite line passes through the circle This function treats 'raySeg' as a line extending infinitely in both directions

Parameters:

  • raySeg: Defines the trajectory (slope and position) of the infinite line.
  • c: The Circle struct to test against.
  • result: If non-nil and an intersection occurs, this is populated with the two intersection points along the infinite line.

func RayTilemapDDA added in v1.4.0

func RayTilemapDDA(pos, dir v.Vec, mag float64, tileMap [][]uint8, cellSize float64, hit *Hit) (bool, image.Point)

RayTilemapDDA performs the DDA (Digital Differential Analysis) algorithm to find intersections with a tile map

youtube.com/watch?v=NbSee-XM7WA

Parameters:

  • pos: Starting position of the ray
  • dir: Direction unit vector of the ray (should be normalized)
  • mag: Maximum distance the ray can travel
  • tileMap: 2D grid of cells where any non-zero value represents a wall/obstacle
  • cellSize: Size of each tile in the grid
  • hit: Optional pointer to Hit struct (can be nil)

Returns:

  • bool: True if a collision occurred
  • image.Point: The grid coordinates of the wall that was hit (0,0 if no hit)

func SegmentCircleOverlap added in v1.3.3

func SegmentCircleOverlap(s *Segment, c *Circle) []v.Vec

SegmentCircleOverlap returns the intersection points of a Segment and a Circle.

If the returned slice is nil, there is no intersection.

The length can be 1 or 2. It can be queried with the len() method.

func SegmentNormal added in v1.3.0

func SegmentNormal(pointA, pointB v.Vec) (normal v.Vec)

SegmentNormal returns surface normal of the segment.

Types

type AABB

type AABB struct {
	Pos  v.Vec // Center position of the box.
	Half v.Vec // Half-extents (half dimensions) from the center.
}

AABB represents an Axis-Aligned Bounding Box.

func NewAABB added in v1.1.2

func NewAABB(centerX, centerY, halfWidth, halfHeight float64) *AABB

NewAABB returns new AABB

func (*AABB) Bottom

func (a *AABB) Bottom() float64

Returns the bottom y-coordinate of the box (usually larger y).

func (*AABB) Height added in v1.1.1

func (a *AABB) Height() float64

Returns the total height (Y dimension) of the box.

func (*AABB) Left

func (a *AABB) Left() float64

Returns the left x-coordinate of the box.

func (*AABB) Max added in v1.2.2

func (a *AABB) Max() v.Vec

Returns bottom-right point

func (*AABB) Min added in v1.2.2

func (a *AABB) Min() v.Vec

Returns top-left point

func (*AABB) Right

func (a *AABB) Right() float64

Returns the right x-coordinate of the box.

func (*AABB) SetBottom

func (a *AABB) SetBottom(b float64)

Sets the bottom y-coordinate and updates Pos.Y accordingly.

func (*AABB) SetLeft

func (a *AABB) SetLeft(l float64)

Sets the left x-coordinate and updates Pos.X accordingly.

func (*AABB) SetRight

func (a *AABB) SetRight(r float64)

Sets the right x-coordinate and updates Pos.X accordingly.

func (*AABB) SetTop

func (a *AABB) SetTop(t float64)

Sets the top y-coordinate and updates Pos.Y accordingly.

func (*AABB) Top

func (a *AABB) Top() float64

Returns the top y-coordinate of the box (usually smaller y).

func (*AABB) Width added in v1.1.1

func (a *AABB) Width() float64

Returns the total width (X dimension) of the box.

type Circle added in v1.1.0

type Circle struct {
	Pos    v.Vec   // Center position of the circle.
	Radius float64 // The radius of the circle.
}

Circle represents a circular bounding volume.

func NewCircle added in v1.2.0

func NewCircle(x, y, radius float64) *Circle

NewCircle returns new Circle

type Hit added in v1.5.0

type Hit struct {
	// The normal vector of the hit.
	Normal v.Vec
	// 1. The time (0.0 to 1.0) along the movement path for moving objects.
	//
	// 2. Penetration depth for overlap tests
	Data float64
}

Hit holds the information about a collision or contact event.

func (*Hit) Reset added in v1.5.0

func (h *Hit) Reset()

Resets the zero values.

type OBB added in v1.4.6

type OBB struct {
	Pos   v.Vec   // Center position of the box.
	Half  v.Vec   // Half-extents (half dimensions) from the center.
	Angle float64 // Rotation angle from center (Pos). Unit in radians. (Clockwise)
}

OBB represents an Oriented Bounding Box

type Segment

type Segment struct {
	A, B v.Vec
}

Segment shape with A and B points.

func NewSegment added in v1.3.2

func NewSegment(ax, ay, bx, by float64) *Segment

NewSegment returns new Segment

type TileCollider added in v1.1.0

type TileCollider struct {
	Collisions      []TileHitInfo // List of collisions from last check
	CellSize        image.Point   // Width and height of tiles
	TileMap         [][]uint8     // 2D grid of tile IDs
	NonSolidTileIDs []uint8       // Sets the ID of non-solid tiles. Defaults to 0.
}

TileCollider handles collision detection between AABB and [][]uint8 2D tilemap

func NewTileCollider added in v1.1.0

func NewTileCollider(tileMap [][]uint8, tileWidth, tileHeight int) *TileCollider

NewTileCollider creates a new tile collider with the given tilemap and tile dimensions

func (*TileCollider) Collide added in v1.1.0

func (c *TileCollider) Collide(box AABB, delta v.Vec, onCollide TileCollisionCallback) v.Vec

Collide checks for collisions when a moving aabb and returns the allowed movement

func (*TileCollider) CollideX added in v1.1.0

func (c *TileCollider) CollideX(aabb *AABB, deltaX float64) float64

CollideX checks for collisions along the X axis and returns the allowed X movement

func (*TileCollider) CollideY added in v1.1.0

func (c *TileCollider) CollideY(rect *AABB, deltaY float64) float64

CollideY checks for collisions along the Y axis and returns the allowed Y movement

type TileCollisionCallback added in v1.1.0

type TileCollisionCallback func([]TileHitInfo, float64, float64)

TileCollisionCallback is called when collisions occur, receiving collision info and final movement

type TileHitInfo added in v1.1.0

type TileHitInfo struct {
	TileCoords image.Point // X,Y coordinates of the tile in the tilemap
	Normal     v.Vec       // Normal vector of the collision (-1/0/1)
}

TileHitInfo stores information about a collision with a tile

Image Directories

Path Synopsis
examples module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL