import { VecN } from '@holotope/core'; /** * The dimension of the region two R⁴ shapes share where they touch. A patch * degenerates to a point in general position and grows as features align: * segment along parallel edges, polygon along parallel 2-faces, polyhedron * where two facets meet flush. */ export type ContactPatchKind4 = 'point' | 'segment' | 'polygon' | 'polyhedron'; /** World-space halfspace `normal.dot(point) <= offset`. */ export interface ContactHalfspace4 { readonly normal: VecN; readonly offset: number; } export interface ContactPlaneIntersectionOptions4 { readonly feasibilityTolerance: number; readonly vertexTolerance: number; readonly rankTolerance: number; readonly maxSolverPoints: number; } export interface ContactPlaneVertex4 { readonly tangent: Float64Array; readonly point: VecN; readonly activeHalfspaces: readonly number[]; } /** * What it cost to find a contact patch by intersecting halfspaces, reported * as the funnel it is. Each count narrows the one before it: * * ```text * constraints → effectiveConstraints → triplesTested * → feasibleCandidates → uniqueVertices → solverPoints * ``` * * The contact plane is three-dimensional, so three halfspace boundaries meet * at a candidate vertex and every triple of effective constraints is tried — * `triplesTested` is cubic in `effectiveConstraints`, which is where the cost * of a large patch lives. Dropping redundant constraints early is therefore * worth far more than it appears from the counts alone. * * A wide gap between `feasibleCandidates` and `uniqueVertices` means many * triples met at the same corner, which is what a degenerate or near-degenerate * patch looks like from here. */ export interface ContactPlaneIntersectionDiagnostics4 { /** Halfspaces supplied, before redundancy is considered. */ readonly constraints: number; /** Those left after redundant ones are dropped; the cubic term uses this. */ readonly effectiveConstraints: number; /** Triples of effective constraints solved for a candidate vertex. */ readonly triplesTested: number; /** Candidates that satisfied every constraint rather than only their own three. */ readonly feasibleCandidates: number; /** Distinct corners remaining once coincident candidates are merged. */ readonly uniqueVertices: number; /** Size of the bounded subset handed to a solver. */ readonly solverPoints: number; } export interface ContactPlaneIntersection4 { readonly kind: ContactPatchKind4; readonly intrinsicDim: 0 | 1 | 2 | 3; readonly vertices: readonly ContactPlaneVertex4[]; readonly solverIndices: readonly number[]; readonly diagnostics: ContactPlaneIntersectionDiagnostics4; } export interface ContactPointReduction4 { readonly kind: ContactPatchKind4; readonly intrinsicDim: 0 | 1 | 2 | 3; readonly solverIndices: readonly number[]; } /** Deterministically reduce coplanar R4 points without losing affine span. */ export declare function reduceContactPoints4(points: readonly VecN[], planeNormal: VecN, maxSolverPoints: number, rankTolerance: number): ContactPointReduction4; /** * Enumerates the bounded intersection of R4 halfspaces inside one contact * hyperplane. The resulting problem is three-dimensional: every vertex is the * feasible intersection of three independent projected boundary planes. */ export declare function intersectContactHalfspaces4(planeNormal: VecN, planeOffset: number, halfspaces: readonly ContactHalfspace4[], options: ContactPlaneIntersectionOptions4): ContactPlaneIntersection4; //# sourceMappingURL=contact-polyhedron4.d.ts.map