Remove the corner helpers akgl_collide_rectangles no longer uses

akgl_rectangle_points, akgl_collide_point_rectangle, akgl_Point and
akgl_RectanglePoints go. They were the intermediate form of an implementation
that changed: akgl_collide_rectangles was eight corner-containment tests built on
them, and it has been four span comparisons since the cross-case fix. Nothing
outside tests/ called either function, and a point-in-rectangle test is four
comparisons a caller can write without a struct conversion in front of them.

akgl_collide_rectangles stays. It has two correct callers in the sidescroller
asking a game-level overlap question -- a coin, a hazard, from an updatefunc --
where a bool is the whole answer and a proxy plus a narrowphase call would be
computing a normal nothing reads. TODO.md records the split rather than leaving
it to be rediscovered.

Public API removal, so 194 exported akgl_ symbols against 196, and the manual's
counts move with them. The perf suite loses its rectangle_points row; the
all-pairs sweep stays as the control it is now labelled, and PERFORMANCE.md says
what 0.8.0 measured against it -- 188.5 us for 32,640 pairs at 256 actors, where
a whole step with collision attached is 54.1 us doing strictly more.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KzBDV2fqgnUAcqCKqKvc71
Co-Authored-By: Andrew Kesterson <andrew@aklabs.net>
This commit is contained in:
2026-08-02 08:09:42 -04:00
parent 36f5f493ea
commit 70c5852f91
11 changed files with 134 additions and 395 deletions

View File

@@ -130,37 +130,6 @@ akerr_ErrorContext *akgl_path_relative(char *root, char *path, akgl_String *dest
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_rectangle_points(akgl_RectanglePoints *dest, SDL_FRect *rect)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, dest, AKERR_NULLPOINTER, "NULL akgl_RectanglePoints reference");
FAIL_ZERO_RETURN(errctx, rect, AKERR_NULLPOINTER, "NULL Rectangle reference");
dest->topleft.x = rect->x;
dest->topleft.y = rect->y;
dest->bottomleft.x = rect->x;
dest->bottomleft.y = rect->y + rect->h;
dest->topright.x = rect->x + rect->w;
dest->topright.y = rect->y;
dest->bottomright.x = rect->x + rect->w;
dest->bottomright.y = rect->y + rect->h;
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_collide_point_rectangle(akgl_Point *p, akgl_RectanglePoints *rp, bool *collide)
{
PREPARE_ERROR(errctx);
FAIL_ZERO_RETURN(errctx, p, AKERR_NULLPOINTER, "NULL Point reference");
FAIL_ZERO_RETURN(errctx, rp, AKERR_NULLPOINTER, "NULL akgl_RectanglePoints reference");
FAIL_ZERO_RETURN(errctx, collide, AKERR_NULLPOINTER, "NULL boolean reference");
if ( (p->x >= rp->topleft.x) && (p->y >= rp->topleft.y) &&
(p->x <= rp->bottomright.x) && (p->y <= rp->bottomright.y) ) {
*collide = true;
} else {
*collide = false;
}
SUCCEED_RETURN(errctx);
}
akerr_ErrorContext *akgl_collide_rectangles(SDL_FRect *r1, SDL_FRect *r2, bool *collide)
{
PREPARE_ERROR(errctx);
@@ -177,13 +146,14 @@ akerr_ErrorContext *akgl_collide_rectangles(SDL_FRect *r1, SDL_FRect *r2, bool *
* all eight tests said no. util.h carried a @note describing the arrangement
* rather than a fix.
*
* `<=` and not `<`, because akgl_collide_point_rectangle is inclusive on all
* four edges and this function has always agreed with it: two rectangles
* sharing exactly one edge collide.
* `<=` and not `<`: two rectangles sharing exactly one edge collide. That is
* what the corner form did, inclusive on all four edges, and changing it
* would silently change what every pickup test in a consumer answers.
*
* The comparison is in float now. The corner form went through akgl_Point,
* whose members are int, so a rectangle at x = 10.9 had its corner at 10 and
* a sub-pixel overlap was invisible.
* whose members were int, so a rectangle at x = 10.9 had its corner at 10
* and a sub-pixel overlap was invisible. That type is gone with the corner
* functions, in 0.8.0.
*/
*collide = ( (r1->x <= (r2->x + r2->w)) &&
(r2->x <= (r1->x + r1->w)) &&