import { VecN } from '@holotope/core'; import { type ContactPatchKind4 } from './contact-polyhedron4.js'; import { HyperplaneColliderN } from './hyperplane-collider.js'; import type { PolytopeBoundaryFeature4 } from './polytope-contact4.js'; import { type ConvexPolytopeTopologyOptionsN } from './polytope-topology.js'; import { type SupportFeatureId, type SupportShapeN } from './support-shape.js'; export interface PolytopeHyperplaneContactOptions4 extends ConvexPolytopeTopologyOptionsN { /** Separation/contact band in world units. Default 1e-12. */ readonly tolerance?: number; /** Band for identifying every vertex of the support face. Default 1e-10. */ readonly manifoldTolerance?: number; /** Spherical Minkowski radius around the polytope. Default 0. */ readonly polytopeMargin?: number; /** Maximum retained solver points. Default 8; must be in [4, 32]. */ readonly maxSolverPoints?: number; } /** * What a polytope–hyperplane test established. Three of these are answers * about the geometry; two are statements about the query itself. * * `unsupported` means the polytope cannot be handled by this path at all — * it is not vertex-enumerable — and no amount of retrying changes that. * `indeterminate` means this attempt failed, at a candidate limit or on a * degeneracy, and a different tolerance might succeed. Neither carries a * measurement, and neither means the shapes are apart. */ export type PolytopeHyperplaneContactStatus4 = 'unsupported' | 'indeterminate' | 'separated' | 'touching' | 'overlapping'; /** * Why the test stopped where it did. `complete` accompanies every genuine * answer; the rest name what prevented one. */ export type PolytopeHyperplaneContactReason4 = 'complete' | 'polytope-not-vertex-enumerable' | 'facet-candidate-limit' | 'degenerate-polytope' | 'facet-enumeration-failed' | 'compiled-topology-invalid' | 'support-feature-invalid'; export interface PolytopeHyperplaneContactVertex4 { readonly id: string; readonly polytopeVertexId: SupportFeatureId; readonly pointA: VecN; readonly pointB: VecN; readonly resolvedPoint: VecN; } export interface PolytopeHyperplaneContactDiagnostics4 { readonly topologySource: 'compiled' | 'enumerated'; readonly sourceVertices: number; readonly facets: number; readonly facetCandidates: number; readonly queryFacetCandidates: number; readonly supportVertices: number; readonly solverPoints: number; } export interface PolytopeHyperplaneContactPatch4 { readonly kind: ContactPatchKind4; readonly intrinsicDim: 0 | 1 | 2 | 3; /** Ordered minimum-translation direction from B toward A. */ readonly normal: VecN; readonly planeNormal: VecN; readonly originalPlaneOffset: number; readonly resolvedPlaneOffset: number; readonly penetrationDepth: number; readonly alignmentShift: number; readonly translationA: VecN; readonly polytopeRole: 'a' | 'b'; readonly polytopeFeature: PolytopeBoundaryFeature4; readonly vertices: readonly PolytopeHyperplaneContactVertex4[]; readonly solverPoints: readonly PolytopeHyperplaneContactVertex4[]; readonly maxResolvedPlaneResidual: number; readonly diagnostics: PolytopeHyperplaneContactDiagnostics4; } /** * Result of testing a convex polytope against an infinite hyperplane. * * Every measurement is nullable because the test can decline to answer: the * polytope may not be vertex-enumerable, or facet enumeration may fail. On * `unsupported` and `indeterminate` all of them are `null` together, so a * caller checks `status` once rather than each field in turn. * * A null measurement is not a separation. Treating either non-answer as * "apart" is the mistake this type is shaped to prevent, and `reason` * distinguishes a permanent limitation from a retryable failure. */ export interface PolytopeHyperplaneContactResult4 { /** Whether the geometry was decided, and if not, why not. */ readonly status: PolytopeHyperplaneContactStatus4; /** `complete` on an answer; otherwise what prevented one. */ readonly reason: PolytopeHyperplaneContactReason4; /** `null` unless the test produced an answer. */ readonly intersects: boolean | null; /** Signed separation, negative once the polytope crosses; `null` on a * non-answer. */ readonly signedDistance: number | null; /** Its magnitude, or `null`. */ readonly distance: number | null; /** Depth of overlap, or `null`. */ readonly penetrationDepth: number | null; /** The plane's unit normal, known regardless of the outcome. */ readonly normal: VecN; /** Which kind of shape was supplied first. */ readonly shapeAType: 'polytope' | 'hyperplane'; /** Which was supplied second. */ readonly shapeBType: 'polytope' | 'hyperplane'; /** Spherical Minkowski radius the polytope was grown by for this test. */ readonly polytopeMargin: number; /** The polytope feature meeting the plane, or `null` on a non-answer. */ readonly polytopeFeature: PolytopeBoundaryFeature4 | null; /** The shared region; `null` when separated, and also on a non-answer. */ readonly patch: PolytopeHyperplaneContactPatch4 | null; } /** Ordered complete support-face contact between an R4 polytope and plane. */ export declare function polytopeHyperplaneContact4(shapeA: SupportShapeN | HyperplaneColliderN, shapeB: SupportShapeN | HyperplaneColliderN, options?: PolytopeHyperplaneContactOptions4): PolytopeHyperplaneContactResult4; //# sourceMappingURL=polytope-plane-contact4.d.ts.map