Skip to content

docs(query): say m2Shape_GetClosestPoint returns an inside point as is - #354

Merged
siracozmen01 merged 1 commit into
mainfrom
closest-point-inside
Nov 5, 2026
Merged

siracozmen01 merged 1 commit into
mainfrom
closest-point-inside

Conversation

@siracozmen01

Copy link
Copy Markdown
Collaborator

Problem

m2Shape_GetClosestPoint's header promises the nearest surface point. For a point inside the shape, or within its radius of the core, the call returns the point itself, as Box2D's does. The header says nothing of that, and no test takes the branch (#353).

Change

  • include/maul2d/shape.h: m2Shape_GetClosestPoint says that a point inside the shape, or within its radius, is its own nearest point and comes back as it is. @return says the same.
  • test/test_world.c gains TestClosestPointFromInside, on a 2 m box and a capsule of radius 0.5:
    • A point inside the box comes back exactly.
    • A point 0.25 m off the capsule's core, within its radius, comes back exactly.
    • A point 0.5 m outside the box comes back on its face, as the near miss.

No result changes: the code is as it was.

Verification

  • test_world passes.
  • Mutants, each built into a scratch library and run against test_world:
Mutant Fails
no inside branch: every point is projected to the surface the capsule check (the box's inside point projects to itself)
the inside branch leaves out the radius the capsule check
  • tools/check.sh changed passes, the documentation check included. The changed file compiles clean with gcc-14 and clang-20 under the strict flags.
  • test_golden prints the 13 lines of test/hashes.txt unchanged in the scalar (linux-clang-20-asan) and AVX2 (linux-clang-20) presets.

Closes #353

@siracozmen01 siracozmen01 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 42c914d: ready. No findings. Read, not run.

The words against ShapeGetClosestPointWorker (src/shape.c:798-825):

  • The query point goes to the body frame in float, and m2ShapeDistance measures it against the core. If d.distance - target.radius <= 0.0f, it returns point, the caller's own m2Pos2, untouched. So "comes back as it is" is exact, bit for bit, for any body position or rotation, not just in the test's unrotated frame.
  • "Or within its radius" is the - target.radius in that test. A point in a rounded shape's skin, as in your capsule case, takes the same branch and comes back unchanged. It is not moved to the skin's outer surface.
  • Otherwise it returns pointA + radius * normal, the surface radius included, rotated back and added to the body position in double. That is the near-miss case.

Two edges, neither a reason to change the words:

  • A point exactly on the surface takes the inside branch and returns itself, which is also its nearest surface point.
  • Whether a point within float rounding of the surface counts as inside depends on the float conversion of rel. The two answers differ by at most that rounding.
  • m2Shape_TestPoint counts a point within 0.005 outside as touching, while this query projects it. The header does not tie the two together, so nothing here is contradicted.

Test:

  • The box point (0.25, 5.5) is inside a 2 m box centered at (0, 5).
  • The capsule point (4, 5.25) is 0.25 m off the core from (3, 5) to (5, 5), within radius 0.5.
  • The near miss (1.5, 5.5) projects to (1, 5.5).

As the body says, only the capsule case catches the no-inside-branch mutant, since a point inside a polygon core projects to itself. The capsule case also catches the radius-left-out mutant. Both exact-equality checks hold because the inside branch returns the input unchanged.

The body has Problem, Change and Verification. The change is docs and a test only.

@siracozmen01
siracozmen01 merged commit 45264e9 into main Nov 5, 2026
30 checks passed
@siracozmen01
siracozmen01 deleted the closest-point-inside branch November 5, 2026 11:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

m2Shape_GetClosestPoint's header misstates an inside point

1 participant