Repository navigation
Release fixes before 3.0.0: area error bound, lighter sphere meshes, exact turned boxes, cone apex refusal - #32
Merged
Merged
Conversation
… normalAtFace (OPE-89) The "Removed in 2.5" list names 2.0 Sphere, shell, classifyPoint and normalAtFace, but the 2.5 to 3.0 table did not say which 3.0 call takes their place. Add rows for Sphere, shell and classifyPoint with the differences from 2.0 (default radius, shell in place, local point and capitalised results), mark the existing normalAtFace row as a 2.0 name removed in 2.5, and point the removed list at the table.
The build ran rollup into dist with no clean step, so a long-lived local dist kept old body-registry chunks and a local npm pack shipped them. clean-dist.mjs removes dist after build-core and before rollup; a node test asserts every top-level script in dist is reachable from an entry. developer.md now describes the clear step.
… (OPE-84) A plane through a pointed cone's axis meets the cone in two rulings that end at the apex. The universal SSI took the branch-end tangent from the cross product of the surface normals, and the cone has no normal at its apex, so the call threw InvalidGeometry (SingularParameterization). No handler builds a cone minus a half-space today, so the case now refuses like the frustum: regular_normal maps a singular point at a branch end to CoverageGap, and details.families names the pair. Review (class 2): 54 probe runs, 9 changed, all from InvalidGeometry to CoverageGap; none changed between built and refused.
… (OPE-47) The sphere and torus grid rules were about 2.8 times too dense per direction: a sphere of radius 0.5 had 54,288 triangles at the static display bucket, with a worst deviation of 6 % of the requested one. Each lat-long quad is a flat trapezoid, so its deviation is at most the widest parallel's sag plus the meridian's sag; the new counts keep each at e/2: sphere sqrt(r/(4e)) per direction, torus sqrt((R+a)/(4e)) and sqrt(a/(4e)). The OPE-29 floor is unchanged. Measured worst deviation 0.477 D (sphere r 0.5, 6,888 triangles) and 0.486 D (torus 1/0.25, 7,728 triangles). 111 of 581 golden keys move, all sphere or torus meshes, display buffers and mesh volumes. The stored sphere, torus and revolved-bowl meshes (recorded from 2.0) are re-recorded from this kernel. Two sphere boolean volume checks now measure at deflection 0.005, inside their unchanged tolerances. Review (class 3): grid path within 0.499 D in every probe; measure volume error at most 0.069 of errorBound.
…s and tori (OPE-85) A circle or ellipse edge, and a cylinder, cone or torus face, on a frame turned against the world axes was boxed through its turned local box. A side was loose when both frame vectors fed one world axis: a mirrored chair arm was 0.0116 m too wide, a full torus up to 1.08 times its major radius. Each world axis now gets the exact range of origin + P cos t + Q sin t (plus the axial term for faces), in floats with an outward pad of 16 eps of the magnitude, intersected with the old box so no box gets wider. Sphere faces and partial tori are as before. The box drives the display bucket, the classification grid and the exchange error bound, so 13 scenes move: grid points, a one-step finer display bucket for the turned torus, bounds of the mirrored graph, and exchange error bounds near 1e-11. No classification verdict changes at a fixed point (344,605 points checked). Review (class 2): worst sample outside a box 2.3e-17, the same as the unchanged path; box cost +3.6 to +7.5 %, classification -0.6 %.
check:duplicates found the two full-circle tests identical after identifier normalising; both now call one helper that takes the frame.
…(OPE-83) measure() returned one errorBound, documented as the volume bound (4 * area * deflection). It has volume units, so it never bounded the area: at size 1e-3 every curved primitive missed it by 7x to 96x. The volume bound holds (worst |error|/bound 0.089 over the corpus). Measure gains areaErrorBound (owner-approved name; the binding appends it as the fifth value). Per triangle it bounds the area against the surface patch with the offset-surface Jacobian and signed projection, which holds for folded triangles; each curved trim chord adds a lune term per face beside the edge; a 1e-10 * area floor covers rounding. A triangle too coarse to bound makes it Infinity. volume, area, errorBound and deflection are bit-identical (258 corpus rows). Corpus: 201 rows measure, worst area error / areaErrorBound 0.888; the 57 refusals (LimitExceeded, UnresolvedTessellation) are unchanged and out of scope. Review (class 3): derivation sound, 34 closed-form probes pass; one fix round for an azimuth rounding case that gave Infinity on slot and rounded-rectangle extrusions. Cost: +8 to +15 %.
OPE-36 left open whether the shell's line-and-arc inset misses a pinch between neighbouring edges away from their shared corner. A probe over seven profile families and necks from 0 to 1e-4 found no such pinch: the inset is an erosion with only convex corners, and the distance from a line or circle to another has one local minimum, so neighbours can only come close again by crossing, which splits or refuses. No code change. Three tests pin the rules (proven by four mutants), and MIGRATION states what is detected: edges that come closer than four times the geometric tolerance and do not share a corner; any inset feature below the inset tolerance can also throw. Review (class 2): about 90 runs over 15 families, every built body valid; one wording fix round.
3.0.0 is not published, so the batch ships as part of it. The version stays 3.0.0. MIGRATION has no 3.0.0 to 3.0.1 section: areaErrorBound, the scoped sync flush and its input checks, the cone apex refusal and the revolve shell families move into 2.5 to 3.0, with three new checks. The pointed cone line in the half-space note now says CoverageGap.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes that go into 3.0.0 before it is published. 3.0.0 is not on npm yet, so the version stays 3.0.0 and the MIGRATION "2.5 to 3.0" section describes all of it.
What a user sees
body.measure()also returnsareaErrorBound:|area − exact| ≤ areaErrorBound. Before, nothing bounded the area, and below unit size the area error was up to several thousand timeserrorBound. In 201 test rows the worst area error is 0.89 of the bound.measureis 8 % to 15 % slower.getBounds()of a circle or ellipse edge, a cylinder or cone face and a full torus on a turned frame is exact. A chair arm mirrored across a slanted plane was 0.0116 m too wide.CoverageGap(messagenames'singular surface point'), notInvalidGeometry.Sphere,shell,classifyPointandnormalAtFaceto their 3.0 calls.npm run buildstarts from an emptydist, so old chunks cannot ship in a local pack.Issues
OPE-89, OPE-90, OPE-84, OPE-47, OPE-85, OPE-83, OPE-86.
Checks
npm run check:full(20 of 20 steps) before it merged into this branch, with a kernel snapshot compared against the one before.check:sourceis clean.Known limits (filed, not in this PR)
classifyPointreturns Inside for some points outside a mirrored cylinder, cone or frustum.UnresolvedIntersection.areaErrorBoundis loose on a torus and can beInfinityfor a triangle too coarse to bound.InvalidTopology.After merge
The
v3.0.0tag points at fbef715, before these fixes. Move it to the merge commit before publishing 3.0.0.