Documentation Index
Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl.Vector/llms.txt
Use this file to discover all available pages before exploring further.
The Intersection static class (Prowl.Vector.Geometry namespace) provides a comprehensive set of low-level, allocation-free intersection and overlap tests. Every method operates on plain value types — Float3, float, bool — so there are no heap allocations at call time. All direction vectors (ray directions, plane normals) are assumed to be normalized unless stated otherwise.
using Prowl.Vector.Geometry;
All methods share a single epsilon constant: Intersection.INTERSECTION_EPSILON = 0.00001f. Distances or denominators smaller than this value are treated as zero to avoid numerical instability.
Ray Tests
RayPlane
public static bool RayPlane(
Float3 rayOrigin,
Float3 rayDir, // normalized
Float3 planeNormal, // normalized
float planeD, // dot(Normal, PointOnPlane)
out float distance)
Returns true if the ray intersects the plane in the forward direction (distance ≥ 0). The plane is specified in dot(Normal, point) = D form. Use Plane.Normal and Plane.D directly.
RayTriangle
public static bool RayTriangle(
Float3 rayOrigin,
Float3 rayDir, // normalized
Float3 v0, Float3 v1, Float3 v2,
out float distance,
out float u,
out float v)
Möller–Trumbore ray–triangle intersection. Tests both front and back faces. Returns the barycentric coordinates u and v of the hit point; the third coordinate is w = 1 − u − v. The intersection point in world space is:
Float3 hitPoint = rayOrigin + rayDir * distance;
// or equivalently:
Float3 hitPoint = (1 - u - v) * v0 + u * v1 + v * v2;
RayAABB
public static bool RayAABB(
Float3 rayOrigin,
Float3 rayDir, // does NOT need to be normalized
Float3 boxMin,
Float3 boxMax,
out float tMin,
out float tMax)
Slab-method ray–AABB intersection. tMin is the entry distance and tMax is the exit distance. If tMin < 0 and tMax ≥ 0, the ray originates inside the box.
RaySphere
public static bool RaySphere(
Float3 rayOrigin,
Float3 rayDir, // normalized
Float3 sphereCenter,
float sphereRadius,
out float t0,
out float t1)
Returns true if the ray hits the sphere. t0 ≤ t1. If the ray starts inside the sphere, t0 will be negative.
RayCylinderInfinite
public static bool RayCylinderInfinite(
Float3 rayOrigin, Float3 rayDir, // normalized
Float3 cylinderAxisPoint, Float3 cylinderAxisDir, // normalized
float cylinderRadius,
out float t0, out float t1)
Intersection with an infinite cylinder. If the ray is parallel and inside the cylinder, t0 = -∞ and t1 = +∞.
RayCylinderCapped
public static bool RayCylinderCapped(
Float3 rayOrigin, Float3 rayDir, // normalized
Float3 capA_Center, // center of first end cap
Float3 capB_Center, // center of second end cap
float radius,
out float distance)
Intersection with a finite capped cylinder. distance is the smallest non-negative hit distance (body or cap).
Overlap Tests
These methods return a simple bool — no distance or point data — and are optimized for high-frequency culling passes.
Sphere–Sphere
public static bool SphereSphereOverlap(
Float3 centerA, float radiusA,
Float3 centerB, float radiusB)
True when distanceSq(centerA, centerB) ≤ (radiusA + radiusB)².
AABB–AABB
public static bool AABBAABBOverlap(
Float3 minA, Float3 maxA,
Float3 minB, Float3 maxB)
Separating-axis test on all three axes.
Sphere–AABB
public static bool SphereAABBOverlap(
Float3 sphereCenter, float sphereRadius,
Float3 boxMin, Float3 boxMax)
Finds the closest point on the AABB to the sphere center and compares the squared distance to radius².
Triangle–Sphere / Triangle–AABB
public static bool TriangleSphereOverlap(
Float3 v0, Float3 v1, Float3 v2,
Float3 sphereCenter, float sphereRadius)
public static bool TriangleAABBOverlap(
Float3 v0, Float3 v1, Float3 v2,
Float3 boxMin, Float3 boxMax)
Both are backed by GJK.Intersects.
Triangle–Triangle
public static bool TriangleTriangle(
Float3 a0, Float3 a1, Float3 a2,
Float3 b0, Float3 b1, Float3 b2)
A combined algorithm: quick AABB early-out, then normal projections, then a full SAT test over all 9 edge-cross-product axes.
Line Segment Overlaps
public static bool LineSegmentSphereOverlap(
Float3 segStart, Float3 segEnd,
Float3 sphereCenter, float sphereRadius)
public static bool LineSegmentAABBOverlap(
Float3 segStart, Float3 segEnd,
Float3 boxMin, Float3 boxMax)
public static bool LineSegmentTriangleOverlap(
Float3 segStart, Float3 segEnd,
Float3 v0, Float3 v1, Float3 v2)
public static bool LineSegmentLineSegmentOverlap(
Float3 seg1Start, Float3 seg1End,
Float3 seg2Start, Float3 seg2End)
Frustum Containment and Overlap
// Point inside all 6 planes
public static bool FrustumContainsPoint(
Float3[] planeNormals, float[] planeDs, Float3 point)
// Sphere not completely behind any plane
public static bool FrustumIntersectsSphere(
Float3[] planeNormals, float[] planeDs,
Float3 sphereCenter, float sphereRadius)
// AABB not completely behind any plane (p-vertex test)
public static bool FrustumIntersectsAABB(
Float3[] planeNormals, float[] planeDs,
Float3 boxMin, Float3 boxMax)
// GJK-backed overlap tests for other shape combinations
public static bool FrustumTriangleOverlap(Frustum frustum, Float3 v0, Float3 v1, Float3 v2)
public static bool FrustumLineSegmentOverlap(Frustum frustum, Float3 segStart, Float3 segEnd)
public static bool FrustumFrustumOverlap(Frustum frustumA, Frustum frustumB)
The FrustumContainsPoint, FrustumIntersectsSphere, and FrustumIntersectsAABB methods take raw arrays of plane normals and D values. Pass frustum.Planes[i].Normal and frustum.Planes[i].D arrays, or use the higher-level methods on the Frustum struct itself (frustum.Contains(point), etc.).
Cone Overlaps
public static bool ConeSphereOverlap(Cone cone, Float3 sphereCenter, float sphereRadius)
public static bool ConeAABBOverlap(Cone cone, Float3 boxMin, Float3 boxMax)
public static bool ConeTriangleOverlap(Cone cone, Float3 v0, Float3 v1, Float3 v2)
public static bool ConeLineSegmentOverlap(Cone cone, Float3 segStart, Float3 segEnd)
public static bool ConeFrustumOverlap(Cone cone, Frustum frustum)
public static bool ConeConeOverlap(Cone coneA, Cone coneB)
All cone overlap tests are backed by GJK.Intersects.
LineSegmentPlane
public static bool LineSegmentPlane(
Float3 segA, Float3 segB,
Float3 planeNormal, float planeD, // planeNormal assumed normalized
out Float3 intersectionPoint)
Tests whether a line segment intersects a plane and returns the world-space intersection point. Returns false if the segment is parallel to the plane (including coplanar cases) or if the intersection falls outside the segment extents.
2D Segment–Segment
public static bool SegmentSegment2DOverlap(
Float2 p1, Float2 p2,
Float2 p3, Float2 p4,
out Float2 intersection,
out float t)
Intersects two 2D line segments and returns the intersection point and the parameter t along the first segment (0–1).
Closest-Point Queries
ClosestPointOnLineToPoint
public static void ClosestPointOnLineToPoint(
Float3 lineA, Float3 lineB,
Float3 point,
out Float3 closestPoint)
Projects point onto the infinite line defined by lineA and lineB. Unlike the segment variant, the result is not clamped and may fall outside the interval [lineA, lineB].
ClosestPointOnLineSegmentToPoint
public static void ClosestPointOnLineSegmentToPoint(
Float3 segA, Float3 segB,
Float3 point,
out Float3 closestPoint)
Projects point onto the segment and clamps to the endpoints.
DistanceSqPointToLineSegment
public static float DistanceSqPointToLineSegment(
Float3 segA, Float3 segB, Float3 point)
Squared distance from a point to a segment (avoids the square root).
ClosestPointOnAABBToPoint
public static void ClosestPointOnAABBToPoint(
Float3 point,
Float3 boxMin, Float3 boxMax,
out Float3 closestPoint)
Component-wise clamping of the point to the box extents.
ClosestPointOnSphereToPoint
public static void ClosestPointOnSphereToPoint(
Float3 point,
Float3 sphereCenter, float sphereRadius,
out Float3 closestPoint)
Projects the point onto the sphere surface. Falls back to center + (radius, 0, 0) when the point coincides with the center.
ClosestPointOnTriangleToPoint
public static void ClosestPointOnTriangleToPoint(
Float3 point,
Float3 v0, Float3 v1, Float3 v2,
out Float3 result)
Voronoi-region decomposition; handles all vertex, edge, and face regions correctly.
ClosestPointsLineSegmentLineSegment
public static void ClosestPointsLineSegmentLineSegment(
Float3 p1, Float3 q1, // segment 1
Float3 p2, Float3 q2, // segment 2
out Float3 c1, out Float3 c2,
out float s, out float t)
Returns the closest pair of points, one on each segment, and their parameters s (on segment 1) and t (on segment 2).
DistanceSqSegmentSegment
public static float DistanceSqSegmentSegment(
Float3 p1, Float3 q1,
Float3 p2, Float3 q2)
Signed Distance and Plane Classification
SignedDistancePointToPlane
public static float SignedDistancePointToPlane(
Float3 point,
Float3 planeNormal, // normalized
float planeD)
dot(Normal, point) − D. Positive on the normal side, negative on the back.
ClosestPointOnPlaneToPoint
public static void ClosestPointOnPlaneToPoint(
Float3 point,
Float3 planeNormal, float planeD,
out Float3 closestPoint)
ClassifyPointToPlane
public enum PlaneIntersectionType { Front, Back, Intersecting }
public static PlaneIntersectionType ClassifyPointToPlane(
Float3 point, Float3 planeNormal, float planeD)
Returns Front if signedDist > EPSILON, Back if < -EPSILON, otherwise Intersecting.
ClassifySphereToPlane / ClassifyAABBToPlane
public static PlaneIntersectionType ClassifySphereToPlane(
Float3 sphereCenter, float sphereRadius,
Float3 planeNormal, float planeD)
public static PlaneIntersectionType ClassifyAABBToPlane(
Float3 boxMin, Float3 boxMax,
Float3 planeNormal, float planeD)
Barycentric Utilities
public static void PointTriangleBarycentric(
Float3 point, Float3 v0, Float3 v1, Float3 v2,
out float u, out float v)
public static bool IsPointInTriangle(float u, float v)
IsPointInTriangle returns true when u ≥ 0, v ≥ 0, and u + v ≤ 1 (with epsilon tolerance).
Full Example
using Prowl.Vector;
using Prowl.Vector.Geometry;
// --- Ray-Triangle Test ---
var rayOrigin = new Float3(0.5f, 5.0f, 0.5f);
var rayDirection = new Float3(0.0f, -1.0f, 0.0f); // pointing down
var v0 = new Float3(0, 0, 0);
var v1 = new Float3(1, 0, 0);
var v2 = new Float3(0, 0, 1);
if (Intersection.RayTriangle(rayOrigin, rayDirection, v0, v1, v2,
out float dist, out float u, out float v))
{
Float3 hit = rayOrigin + rayDirection * dist;
Console.WriteLine($"Hit at {hit}, u={u:F3}, v={v:F3}");
// Hit at (0.5, 0, 0.5), u=0.500, v=0.500
}
// --- Sphere-Sphere Overlap ---
bool touching = Intersection.SphereSphereOverlap(
centerA: new Float3(0, 0, 0), radiusA: 2.0f,
centerB: new Float3(3, 0, 0), radiusB: 1.5f);
// touching = true (distance 3.0 == 2.0 + 1.0 ... wait, 2.0+1.5=3.5 > 3.0)
Console.WriteLine(touching); // True
All direction vectors passed to ray-intersection methods are assumed to be normalized unless the documentation for that specific overload says otherwise (RayAABB explicitly relaxes this requirement). Passing an un-normalized direction to the other ray methods will produce incorrect distances.