Skip to content

No in-plane coordinate frame, and plane orthonormality was decided with the linear tolerance #94

Description

@GeneralPawz

Problem

The kernel had no in-plane coordinate frame with behaviour. Frame2 and Frame3 in axiolid-core are inert storage: they hold axes but own no operations and enforce no invariant. Every consumer therefore re-derived the same two mappings and its own validity rule.

Four separate orthonormality checks existed under three different tolerance policies:

site policy
planar/project/src/lib.rs tolerance.linear()
sampled/field/src/config.rs tolerance.angular()
parametric/evaluate/src/surface.rs hardcoded 1e-9
execution/dispatch/src/section.rs ad hoc

The defect this caused

Orthonormality is decided by a dot product of two unit vectors, which is dimensionless. project::Plane::validate compared it against the linear tolerance, tying a pure direction test to the model length unit.

Under Tolerance::MILLIMETRE the linear tolerance is 1e-3, so a basis skewed by up to 0.5 milliradians passed as orthonormal. Projection then used a non-orthogonal basis as if it were orthogonal, and every projected coordinate was silently wrong. The same basis was correctly refused under Tolerance::METRE.

Failing test before the fix:

a_skewed_plane_is_refused_under_millimetre_tolerance ... FAILED
a 0.5 mrad skewed basis must be refused regardless of the length unit

Fix

Added PlaneFrame to axiolid-core: private fields, validated construction, and both directions of the map (project, lift, signed_distance, normal).

  • validity is decided with the angular tolerance, so it no longer depends on the length unit
  • fields are private, so a skewed basis is unrepresentable rather than merely rejected
  • the normal is derived (x cross y) rather than stored, so it cannot disagree with the axes
  • from_normal builds a valid frame when the caller cares about the plane but not the in-plane x direction, seeding against the least-aligned world axis for stability

axiolid_project::Plane is now an alias for it. The old ProjectionError::InvalidPlane is unreachable and documented as such, retained because removing a public variant is breaking.

Verification

  • 6 new tests, including a round-trip invariant and a from_normal-always-valid property over 6 normals
  • mutation-tested: reverting angular() to linear() makes a_skewed_basis_is_refused_in_every_unit_system fail, so the guard is real rather than decorative
  • workspace 1107 passed / 0 failed

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

needs-triageFiled but not yet accepted, sized, or scheduled

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions