-
-
Notifications
You must be signed in to change notification settings - Fork 19
bounds and geometry
FixedMathSharp geometry is dimension-explicit and engine-agnostic. It provides reusable shape math; physics policy such as colliders, materials, broad-phase layers, impulses, and contact response belongs in a higher-level simulation package.
Add using FixedMathSharp.Geometry; for bounds and most primitives.
FixedConvexPrismRelations remains in the root FixedMathSharp namespace for
API compatibility.
| Shape | Type | Typical use |
|---|---|---|
| 2D axis-aligned area | FixedBoundArea |
Grids, footprints, planar broad-phase bounds |
| 2D circle | FixedBoundCircle |
Radial planar containment and overlap |
| 3D axis-aligned box | FixedBoundBox |
Volumes and broad-phase bounds |
| 3D sphere | FixedBoundSphere |
Radial volume containment and overlap |
| 3D oriented box | FixedOrientedBox |
Rotated box geometry without cached corners |
| 3D view frustum | FixedBoundFrustum |
Plane-based frustum classification |
A flat world footprint is a FixedBoundArea plus explicit layer, elevation, or
height state in your application. Use FixedBoundBox when the query is truly
volumetric.
| Dimension | Types |
|---|---|
| 2D |
FixedRay2d, FixedSegment2d, FixedTriangle2d, FixedPointAnchor2d
|
| 3D |
FixedRay, FixedPlane, FixedSegment, FixedTriangle, FixedPointAnchor
|
| Cross-shape helpers |
FixedSlabProjection, convex relation helpers, contact-anchor values |
Start with the simple bound or primitive that represents your data. Reach for a centered-axis, sweep, slab, or anchor API only when materializing intermediate world coordinates would lose information.
Named factories keep extent meaning visible:
FixedBoundBox room = FixedBoundBox.FromCenterAndSize(
center,
new Vector3d(10, 4, 10));
FixedBoundArea footprint = FixedBoundArea.FromCenterAndScope(
center2d,
new Vector2d(5, 2));
FixedBoundBox exactEndpoints = FixedBoundBox.FromMinMax(min, max);-
FromMinMaxsorts swapped endpoint components. -
FromCenterAndSizetakes total size. -
FromCenterAndScopetakes half-extents. - Negative size/scope components are normalized by absolute value.
Ordinary centered factories are strict: they throw when a required endpoint is
outside Q32.32. Use a factory named *ClippedToDomain only when you explicitly
want the intersection between the conceptual shape and the representable
coordinate domain.
Derived Size/Proportions values throw when the exact positive span does not
fit in Fixed64. Scope rounds outward when needed so it does not
underestimate the stored endpoints.
Circle and sphere radii are normalized by absolute value during construction, assignment, and serialized-state load.
Default containment and intersection include the boundary:
- a point on an edge, face, or surface is contained;
- touching edges, faces, corners, and tangencies intersect; and
- a ray that starts inside or on a bound can report
Fixed64.Zero.
Use IntersectsStrict where the API offers it when you need positive area or
volume rather than touch-inclusive overlap.
bool touchesOrOverlaps = first.Intersects(second);
bool positiveVolume = first.IntersectsStrict(second);There is no global geometry epsilon. Individual members document whether they
use exact comparison, Fixed64.Epsilon, inclusive boundaries, or strict
interiors.
Geometry routinely compares products and squared distances that are larger than their final public result. FixedMathSharp widens those intermediates before it chooses a side, candidate, root, or witness.
The practical rules are:
- Decisions are made from exact fixed-width intermediates where the member promises full-domain behavior.
- A public point, distance, depth, or parameter is rounded only at the final boundary.
- A
Try*method reports its documented query/output failure atomically. Invalid arguments may still throw. - Clipped APIs clip only the conceptual final boundary; they do not silently shorten inputs before the query.
See Full-Domain Arithmetic for the numeric model behind these contracts.
FixedBoundBox is the general 3D axis-aligned bound. It supports containment,
intersection, clamping, projection, merging, and cross-type relations with
spheres, frustums, planes, and rays.
FixedOrientedBox stores a center, a normalized quaternion, and strictly
positive half-extents:
FixedOrientedBox box = new(center, normalizedRotation, halfExtents);
FixedBoundBox broadPhase = box.GetBoundsClippedToDomain();
Vector3d localSupport = box.GetLocalSupportPoint(direction);
if (box.TryMaterializeLocalPoint(localSupport, out Vector3d worldSupport))
{
// The selected world point fits in Q32.32.
}default(FixedOrientedBox) is invalid. Queries derive an exact rational basis
from the stored quaternion, so negating every quaternion component does not
change the represented geometry. Value equality remains structural, however;
the two stored quaternion signs are different values.
Support and corner features are center-relative. Materialization returns
false when the final world point is outside the coordinate domain.
Rays do not normalize their direction. A returned ray parameter is a physical distance only when the caller supplied a normalized direction.
FixedRay ray = new(origin, Vector3d.Right);
Fixed64? distance = ray.Intersects(box);
if (distance.HasValue)
{
Vector3d hit = ray.GetPoint(distance.Value);
}GetPoint uses a fused multiply-add per coordinate. TryGetPoint uses the same
calculation but returns false instead of saturating when a final coordinate is
not representable.
Segments preserve endpoint order. Reversing a segment keeps the same bounds but produces a different value. Closest-point and closest-pair queries use stable candidate order for exact ties.
FixedSegment path = new(start, end);
Vector3d closest = path.ClosestPoint(point);
Fixed64 distanceSquared = path.DistanceSquared(point);
(Vector3d a, Vector3d b) = path.GetClosestPoints(otherPath);For a long authored path, prefer physical-distance interval APIs when available. They keep the original chord components until the final mapping into the caller-supplied distance range. This preserves small transverse motion that could be lost by normalizing the path first.
Centered capsule, cylinder, and cone helpers describe endpoints and cap planes
from a center, normalized axis, full axis length, and radius. The conceptual
endpoints do not have to fit in Fixed64 as long as the requested final result
does.
Use them when a shape sits near a scalar-domain boundary or when combining the center and half-axis first would saturate.
- Capsule axis length may be zero and then reduces to a circle or sphere.
- Cylinder and cone length must be positive.
- Expanded overloads keep authored dimensions and nonnegative expansion values separate to avoid saturating a combined radius or length.
-
FixedSegment2downs 2D capsule containment, support, endpoint, distance, and intersection helpers. -
FixedSegmentowns the corresponding 3D capsule helpers plus cylinder, cone, swept-sphere, and rounded-box queries.
The exact overload names and argument preconditions are listed on the
FixedSegment2d
and
FixedSegment
API pages.
Interval queries return the closed portion of a bounded segment or ray that intersects the requested shape. Advanced overloads can also report endpoint containment independently of rounded interval parameters.
Choose the represented boundary carefully:
- A capsule is the spherical dilation of a segment.
- A finite cylinder has a side and flat caps.
- A swept sphere against a cylinder rounds the cylinder rim; independently expanding radius and height describes a different sharp-rim volume.
- A swept sphere against a box rounds edges and corners; expanding each box extent describes a larger box, not the same boundary.
This distinction is why the API exposes named sweep methods instead of treating every query as an expanded axis-aligned bound.
Triangles preserve vertex order. FixedTriangle2d exposes planar barycentric
weights; FixedTriangle names its projected barycentric APIs explicitly so a
projection is not confused with strict on-plane containment.
FixedTriangle triangle = new(a, b, c);
Vector3d closest = triangle.ClosestPoint(point);
bool onTriangle = triangle.Contains(point);
bool projectionInside = triangle.ContainsProjection(point);Degenerate triangles retain deterministic edge/point behavior. Closest-feature ties follow stable edge order.
Rigid triangle-pair queries return FixedContactAnchors:
bool hit = first.TryGetContact(
firstOrigin,
firstRotation,
secondOrigin,
secondRotation,
second,
out FixedContactAnchors contact);The normal points from the first triangle toward the second. Each anchor stays in its input rigid frame, so the relation can remain valid even when an absolute world witness cannot be materialized. Exact touching is included and reports zero depth.
FixedPointAnchor and FixedPointAnchor2d keep a point in a rigid local frame.
Use relative-offset or frame-reexpression methods when possible; call
TryGetPoint only when you actually need an absolute coordinate.
Anchors can compare squared distances exactly without materializing either distance. Contact relations use them to retain stable local features across large translations.
FixedSlabProjection returns X/Z support for a centered capsule, cylinder, or
cone clipped to an inclusive world-Y range. It is useful for layered spatial
systems that need a finite vertical silhouette, but it is not a collider or
physics-response API.
| Task | Start with |
|---|---|
| Cross-type bound relations |
FixedBoundArea, FixedBoundBox, FixedBoundCircle, FixedBoundSphere
|
| Oriented-box support and relations | FixedOrientedBox |
| Segment/ray versus capsule, cylinder, or cone |
FixedSegment2d, FixedSegment, FixedRay2d, FixedRay
|
| Swept sphere versus cylinder or box | FixedSegment |
| Centered shape support, containment, or materialization |
FixedSegment2d, FixedSegment static helpers |
| Shape support inside a world-Y layer | FixedSlabProjection |
| Triangle contacts or finite-shape relations | FixedTriangle |
| Relative witnesses outside ordinary world-coordinate range |
FixedPointAnchor, FixedPointAnchor2d, contact-anchor types |
Browse the
FixedMathSharp.Geometry API
for exact overloads, exceptions, tie-breaking rules, and final-result behavior.