Finite-shape contacts
These advanced contracts cover cylinder, cone, and vertical convex-prism contacts. Start with Bounds and Geometry for shape selection and shared query semantics.
Cylinder contacts
FixedOrientedBox.TryGetCenteredCylinderContact includes the box's faces, edges
and vertices against the finite cylinder's caps, side and rims. It finds the
minimum translation without replacing the cylinder with a capsule. A zero radius
is a finite axis segment. The manifold overload additionally clips up to four
matched contacts when a parallel box face and cylinder cap are selected; other
features use the primary contact with a zero manifold count.
FixedTriangle.TryGetCenteredFiniteCylinderContact includes the triangle's
face, edges and vertices against the finite cylinder's caps, side and rims. It
returns a triangle-to-cylinder normal, depth and shape-local contact anchors. A
triangle's closest point to the cylinder center is not sufficient to decide
contact: another part of the triangle can cross a flat cap or a curved rim.
Degenerate triangles return false, matching the triangle/slab contact APIs.
TryGetCircleSlabContact uses the same geometry for an upright finite cylinder,
while retaining the circle's authored yaw and half-thickness. Half-thickness is
not doubled in Fixed64, so a representable slab is not shortened when its full
height exceeds the scalar range. TryGetCenteredCapsuleSlabContact describes a
planar capsule (a rectangle with semicircular ends) extruded through a flat Y
slab, not a rounded 3D capsule. Its contact query covers both rounded ends, the
straight sides, and the flat caps, including oblique rim contacts. Contact
points are paired on the selected features; a straight-side or cap contact can
lie between the rounded ends. The query retains the authored local axis and yaw,
including half-raw endpoints from odd raw core lengths. A zero core uses the
cylinder path above, with the same contact anchors.
Hull contacts for coordinated consumers
The internal closed-hull/cylinder contact path used by coordinated consumers ranks these finite feature families across the complete hull. A shared rational cylinder chart preserves exact ordering between triangles; the triangle that first supplies a supporting direction need not contain its matched witness. An exact inscribed-ball bound can certify a minimum before the remaining features are enumerated. Its contained-center entry includes hull boundaries; declining center admission does not imply separation for an exterior center. The same internal reducer admits finite stadium slabs through a shared planar core chart, retaining endpoint regions and straight-section seam witnesses. An expanded-hull ball certificate includes every original face and supported edge/core extrusion facet; an uncertified seed is discarded before the complete feature search. Affine seam products retain wider fields without widening the native rigid path or rounding a conceptual core endpoint.
Cylinder pairs
FixedSegment.TryGetCenteredFiniteCylinderCapsuleContact includes the finite
cylinder's caps, side, and rims when finding the minimum translation. It also
handles a capsule core that enters the cylinder: depth is not necessarily just
the capsule radius. A zero-length capsule core is a sphere; a zero-radius
cylinder is its finite axis segment.
FixedSegment.TryGetCenteredFiniteCylindersContact similarly finds the minimum
translation between two finite cylinders, including side/rim and rim/rim
constraints. Testing only the axes and their cross product is insufficient for
general finite cylinders. Parallel pairs use a simpler exact path; general
interacting rims require substantially more work. Measure the contact workloads
that occur in your simulation, not only the ordinary parallel case.
Depth, witnesses, and stack usage
Classification and depth ordering use the exact authored geometry. Exact
tangency is contact with zero depth, and a sub-raw separation remains a miss.
Only the selected normal and complete depth are rounded; DepthIsClamped
distinguishes conceptual overflow from an exactly representable maximum. Equal
minima follow stable feature order. Continuous radial ties use a representative
in the authored cylinder frame.
The returned anchors retain independently selected shape-local support features. They are not a promise that two algebraic closest points were rounded together or that the materialized anchors coincide at every tangency. Box anchors retain the exact selected direction's support signs even if a tiny normal component rounds to zero.
Curved oblique contacts require more work than ordinary cap/side contacts. The query allocates no managed memory, but its exact fallback can use hundreds of KiB of bounded stack scratch. Avoid deliberately small-stack worker threads; allow at least a 1 MiB thread stack with adequate headroom for the caller.
Cylinder pairs use the same finite-segment contact path when either radius is zero. The stack guidance above applies to both positive-radius and zero-radius oblique pairs. A zero-radius shape's anchor can lie at the segment center when its whole core supports the selected normal; callers should not require a particular endpoint in a tie.
Triangle/cone contacts
FixedTriangle.TryGetCenteredFiniteConeContact finds an inclusive minimum-depth
contact with a finite cone whose local axis is +Y: the base is at -height/2
and the apex at +height/2. It includes triangle face, edge and vertex features
against the base disk, curved rim, apex and lateral generators. The normal
points from triangle toward cone; depth and both anchors come from that same
selected feature.
Equal minima retain the earlier feature. When both axial exits share the minimum for a horizontal face, the earlier +Up candidate retains the base witness. Witness coordinates whose radical terms vanish or cancel use exact rational nearest-even rounding, including signed half-raw ties and scalar extrema.
Both frame rotations must be normalized, height must be positive, and radius
must be nonnegative. A zero radius is the identical axial-segment relation used
by the cylinder contact query. A segment piercing a triangle can require a
positive exit distance even though the segment has no volume. Degenerate
triangles follow FixedTriangle.IsDegenerate and return false.
Classification precedes final rounding: exact touching is contact, a genuine
positive gap is not, and a tiny overlap can round to zero depth. Anchors retain
the authored frames even when the relative center or absolute world witness
cannot be materialized as a Vector3d. Curved contacts have the same bounded
stack-scratch considerations described above.
Coplanar patches and convex polygons
The internal cone contact owner can also certify a minimum face exit for a borrower-owned connected coplanar patch. The borrower supplies trusted seam topology and every exposed perimeter edge, including holes. Exact projection membership in a seed triangle establishes membership in the actual patch; unrounded boundary clearances then certify either a radius-depth tube around an actual cone chord or the whole cone projection enlarged by that depth. The center's signed side chooses each perimeter half-plane; exact cone support clearance preserves concave patches without filling their holes. Rational quaternion frames and complete cone support avoid rounded intermediate extrema. A failed certificate leaves complete single-triangle feature selection available.
For a trusted filled convex polygon, the internal owner also solves its complete face, perimeter-edge and corner normal fan. An ordered strict-corner loop excludes collinear subdivisions. Corner charts admit only globally supporting features before classifying separation; their artificial diagonals never become contacts. One unreduced rational frame and squared-value scale retain exact ranking across analytic candidates and stationary rim roots. A complete polygon fan admits supporting generator slices before materializing paired witnesses. The borrower establishes convex topology and supplies an intersecting seed for base-pole witnesses. Supplied local witness bounds may contain the whole patch, allowing face coordinates outside the seed triangle to round without restricting them to that triangle. This internal contract does not validate topology or determine a whole noncoplanar surface union's minimum exit.
TryGetCenteredFiniteConeSupportContact is a different operation: it projects
one caller-selected cone support onto the triangle. A failed support projection
does not prove that the complete shapes are separated. Use the complete contact
query when deciding whether the shapes intersect.
Vertical convex-prism contacts
FixedConvexPrismRelations provides contacts against a convex footprint
extruded through a positive Y half-thickness. Footprint offsets are
boundary-ordered in either winding; repeated or collinear offsets retain their
finite closed extent. Touching counts as contact, including zero-radius finite
axes. The shape's local axis and rotation remain separately authored.
TryGetSphereContact and TryGetCenteredCapsuleContact start with canonical
projection axes and certify finite opposing supports. Clip an exposed capsule
core to the selected native-yaw prism plane; keep its midpoint when admitted,
otherwise its nearest finite parameter. An empty projection is completed by the
exact closest core/real-edge pair, including horizontal rims and vertices. Each
exit retains the same signed depth, normal and opposing feature, including
containment. Translate the shape opposite that normal to follow the exit;
equal-depth axes and equivalent finite core parameters retain stable order.
Apply the radius before radial-direction rounding, so full-domain radii do not
amplify an already rounded unit normal's error.
TryGetCenteredCylinderContact and TryGetCenteredConeContact find the minimum
exit through the complete support fan. Prism faces, real edges and vertices meet
the cylinder's caps, side and rims, or the cone's base disk and rim, apex and
lateral generators. Complete closed admission precedes depth selection;
projection overlap alone does not establish intersection. The authored local
axis retains its actual squared norm, and the prism retains its scalar yaw.
Classification, feature admission and minimum-depth ordering are exact. Touching
returns zero depth; a tiny positive overlap can also round to zero. Equal minima
retain stable feature order. The normal points from the curved primitive toward
the prism, so the exact minimum translation moves the primitive opposite that
direction to the touching boundary. DepthIsClamped distinguishes an exact
minimum above Fixed64.MaxValue.
Rounding and witness frames
The selected depth, unit-normal components and witness coordinates round
nearest-even only at the public boundary. An unclamped depth has at most half a
raw unit of error. Normal rounding also matters when reconstructing that
unclamped exit: with e = 2^-33, interpreting the returned scalars exactly
gives a displacement error of at most e + Depth * sqrt(3) * e from the exact
minimum translation. Each subsequent Fixed64 component product can add another
half raw unit of rounding error. A strict separating move needs margin for those
final rounding terms; touching remains contact.
Both witnesses are matched on the selected finite support features before coordinate rounding. Their origins remain the primitive center and prism origin, respectively, while both anchors use the primitive's quaternion frame. This preserves the native scalar-yaw footprint without introducing a rounded prism quaternion. Materialize or compare points through the anchor operations; the second anchor's local coordinates are expressed in that retained frame. Separate additive terms preserve coordinates outside a single scalar's range. Curved prism contacts use the bounded stack scratch described above.