← shapes · version 0.5.4
16 public items, in source order. Generated from the registry index, which re-derives them from the package source at publish time — so a signature here is the one that version actually ships.
pub struct Rect { rx: float, ry: float, rw: float, rh: float }
Axis-aligned bounding box for 2D collision.
pub fn rects_overlap(a: const Rect, b: const Rect) -> boolean
Test whether two axis-aligned rectangles overlap. The comparison is STRICT, so rectangles sharing an edge do NOT overlap.
pub fn circles_overlap(a: const Circle, b: const Circle) -> boolean
Test whether two circles overlap. Strict, like rects_overlap: tangent circles do NOT overlap.
pub fn rect_circle_overlap(r: const Rect, c: const Circle) -> boolean
Test whether a rectangle and a circle overlap. A true circle test — the circle's bounding box is NOT a substitute for it, and a circle wholly inside the rectangle counts as overlapping.
pub fn rect_overlap_depth(a: const Rect, b: const Rect) -> Overlap
Compute the overlap depth between two rectangles on each axis: how far one must move along that axis to stop overlapping, the smaller of the two ways out — not how much of it lies inside the other. Both depths are UNSIGNED distances — the caller derives the direction from the relative positions. Returns (0.0, 0.0) when they don't overlap. Useful for bounce direction: if ox < oy → horizontal bounce.
pub fn aabb_overlap(ax: float, ay: float, aw: float, ah: float, bx: float, by: float, bw: float, bh: float) -> boolean
Test AABB overlap using raw coordinates (no struct allocation — safe in loops). Same strict boundary as rects_overlap.
pub fn aabb_depth_x(ax: float, ay: float, aw: float, ah: float, bx: float, by: float, bw: float, bh: float) -> float
Compute the AABB overlap depth on the X axis using raw coordinates — aabb_depth_y is the other half of the pair, and each call re-runs the overlap test on its own. Unsigned, like rect_overlap_depth. 0.0 means the two do not overlap AT ALL (a real overlap always penetrates by strictly more than zero), not "they meet with no penetration on this axis". Safe in loops (no struct allocation).
pub fn aabb_depth_y(ax: float, ay: float, aw: float, ah: float, bx: float, by: float, bw: float, bh: float) -> float
Compute the AABB overlap depth on the Y axis using raw coordinates — the other half of the aabb_depth_x pair, with the same unsigned 0.0-is-no-overlap contract. Safe in loops (no struct allocation).
pub struct Proxy { boxes: vector<Rect> }
A shape approximated by a SET of boxes rather than one.
A sprite's silhouette is rarely a rectangle, and a single bounding box around a diagonal or an L is mostly empty — a mover well clear of the art still reads as a hit. A handful of boxes tracks the silhouette closely enough to fix that while staying axis-aligned, so every test below is still the cheap one.
The contract a producer owes is CONTAINMENT: every box together must cover everything solid, so substituting the proxy for the art can only ever over- report a hit, never miss one. A system validated against the proxy therefore stays valid when the art changes. Containment alone is satisfied by a screen-sized box, which is why a producer also bounds the OVERSHOOT — see overshoot.
Measured over a 36-sprite corpus (@PLN146 F7a): 16 boxes banded along the tighter axis beat a convex hull on mean, median and worst case, and need no shape kind this library does not already have.
pub fn proxy_hits(self: const Proxy, r: const Rect) -> boolean
Does anything in the proxy overlap r?
The set test every consumer would otherwise write, with the same STRICT boundary as rects_overlap — a box sharing an edge does not overlap. An EMPTY proxy answers false: nothing solid was derived, so nothing can be hit, which is the answer that keeps a sprite with no opaque texels from colliding with the world.
pub fn proxies_overlap(self: const Proxy, other: const Proxy) -> boolean
Do two proxies overlap anywhere?
Pairwise, because a proxy is small by construction — 16 boxes against 16 is 256 rect tests in the worst case and stops at the first hit. Cull with the cheap bounds() box first when both are large.
pub fn bounds(self: const Proxy) -> Rect
The single box containing every box in the proxy — the AABB it replaces.
Useful as a broad-phase cull before proxies_overlap, and as the denominator when judging whether the proxy earned its extra boxes. An empty proxy answers a zero-size box at the origin.
pub fn area(self: const Proxy) -> float
Total area of the proxy's boxes.
Bands from one derivation do not overlap, so for a banded proxy this is the covered area exactly. A proxy whose boxes DO overlap counts the shared part twice, which overstates the area and therefore the overshoot — the honest direction for a bound.
pub fn overshoot(self: const Proxy, solid: float) -> float
How much bigger the proxy is than the thing it stands for, as a fraction.
solid is the area actually covered by art — the opaque texel count for a sprite. 0.0 is exact, 1.0 is twice the size. This is the number a packer gates on, and the reason containment alone is not the contract: a screen-sized box contains everything and is useless.
A solid of zero or less answers 0.0 rather than dividing: there is nothing to be a multiple OF, and a null here would propagate into a comparison that then silently passes.
The trailing ? is not redundant with that guard. A divide types float? whatever the code above it proves, so without the discharge this returns a null into a non-null float — which is the very failure the guard is there to prevent, arriving by the other door.