Skip to content
Back to skills

Hierarchical Collision Cascade

ASecurity

Three-level polygon overlap test — AABB early exit, then point-in-polygon ray casting, then segment intersection — for fast non-convex collision detection

  • 61 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
developmentpythongo

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill hierarchical-collision-cascade --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hierarchical Collision Cascade?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Hierarchical Collision Cascade
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-hierarchical-collision-cascade/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-hierarchical-collision-cascade)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tabular-hierarchical-collision-cascade
description: Three-level polygon overlap test — AABB early exit, then point-in-polygon ray casting, then segment intersection — for fast non-convex collision detection
---

# Hierarchical Collision Cascade

## Overview

Full polygon intersection is expensive for complex shapes. A three-level cascade tests cheapest first: (1) axis-aligned bounding box overlap — rejects most non-colliding pairs instantly, (2) point-in-polygon via ray casting — catches containment cases, (3) edge-edge segment intersection — catches crossing edges. Each level filters candidates for the next, achieving near-O(1) for well-separated objects.

## Quick Start

```python
import numpy as np

def aabb_overlap(a_bounds, b_bounds):
    ax0, ay0, ax1, ay1 = a_bounds
    bx0, by0, bx1, by1 = b_bounds
    return not (ax1 < bx0 or bx1 < ax0 or ay1 < by0 or by1 < ay0)

def point_in_polygon(px, py, polygon):
    n = len(polygon)
    inside = False
    j = n - 1
    for i in range(n):
        xi, yi = polygon[i]
        xj, yj = polygon[j]
        if ((yi > py) != (yj > py)) and \
           (px < (xj - xi) * (py - yi) / (yj - yi) + xi):
            inside = not inside
        j = i
    return inside

def segments_intersect(a1, a2, b1, b2):
    d1 = cross2d(b2 - b1, a1 - b1)
    d2 = cross2d(b2 - b1, a2 - b1)
    d3 = cross2d(a2 - a1, b1 - a1)
    d4 = cross2d(a2 - a1, b2 - a1)
    return (d1 * d2 < 0) and (d3 * d4 < 0)

def polygons_overlap(poly_a, poly_b):
    if not aabb_overlap(bounds(poly_a), bounds(poly_b)):
        return False
    for pt in poly_a:
        if point_in_polygon(pt[0], pt[1], poly_b):
            return True
    for pt in poly_b:
        if point_in_polygon(pt[0], pt[1], poly_a):
            return True
    for i in range(len(poly_a)):
        for j in range(len(poly_b)):
            if segments_intersect(
                poly_a[i], poly_a[(i+1) % len(poly_a)],
                poly_b[j], poly_b[(j+1) % len(poly_b)]):
                return True
    return False
```

## Workflow

1. **AABB check**: compare bounding boxes — if no overlap, return False immediately
2. **Point-in-polygon**: test if any vertex of A is inside B, or vice versa
3. **Segment intersection**: test all edge pairs for crossing
4. Return True only if any check at levels 2-3 passes

## Key Decisions

- **Order matters**: AABB is O(1), PIP is O(v), segment is O(v^2) — cheap filters first
- **vs Shapely**: this cascade in C/NumPy is 10-100x faster for hot loops
- **Touching vs overlapping**: shared vertices/edges need epsilon tolerance
- **Combine with STRtree**: use spatial index to find AABB candidates, then cascade for exact check

## References

- [Why Not](https://www.kaggle.com/code/jazivxt/why-not)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.