Struct LengthRay2
Represents a ray in 2D space — a half-line starting at a point (Position) and extending infinitely in one direction (Direction).
A ray is useful when direction and starting point matter but there is no fixed endpoint: projectile trajectories, line-of-sight checks, sensor cones, and raycasting all fit naturally into this type.
A ray can be converted to a finite LengthSegment2 via WithMagnitude(Length) and to an infinite LengthLine2 via AsLine().
public readonly record struct LengthRay2 : IEquatable<LengthRay2>
- Implements
- Inherited Members
- Extension Methods
Examples
// Ray starting at (1, 0), pointing right
var ray = new LengthRay2(LengthPoint2.FromMeters(1, 0), Direction2.FromDegrees(0));
Constructors
LengthRay2(LengthPoint2, Direction2)
Represents a ray in 2D space — a half-line starting at a point (Position) and extending infinitely in one direction (Direction).
A ray is useful when direction and starting point matter but there is no fixed endpoint: projectile trajectories, line-of-sight checks, sensor cones, and raycasting all fit naturally into this type.
A ray can be converted to a finite LengthSegment2 via WithMagnitude(Length) and to an infinite LengthLine2 via AsLine().
public LengthRay2(LengthPoint2 Position, Direction2 Direction)
Parameters
PositionLengthPoint2The origin of the ray.
DirectionDirection2The direction in which the ray extends. The ray does NOT extend in the opposite direction.
Examples
// Ray starting at (1, 0), pointing right
var ray = new LengthRay2(LengthPoint2.FromMeters(1, 0), Direction2.FromDegrees(0));
Properties
Direction
The direction in which the ray extends. The ray does NOT extend in the opposite direction.
public Direction2 Direction { get; init; }
Property Value
Position
The origin of the ray.
public LengthPoint2 Position { get; init; }
Property Value
Methods
AsLine()
Returns the infinite LengthLine2 that contains this ray.
public LengthLine2 AsLine()
Returns
- LengthLine2
A line through Position with the same Direction as this ray.
Examples
var ray = new LengthRay2(LengthPoint2.FromMeters(1, 2), Direction2.FromDegrees(45));
var line = ray.AsLine();
// line extends infinitely in both the 45° and 225° directions through (1, 2)
Contains(LengthPoint2, Length)
Returns true when point lies on this ray
within tolerance. A point is "on the ray" only if it is
in front of the origin (non-negative parameter) and within the tolerance distance.
This delegates to HasPoint(LengthPoint2, Length).
public bool Contains(LengthPoint2 point, Length tolerance)
Parameters
pointLengthPoint2The point to test.
toleranceLengthMaximum perpendicular distance for the point to be "on" the ray.
Returns
Examples
var ray = new LengthRay2(LengthPoint2.Origin, Direction2.East);
ray.Contains(LengthPoint2.FromMeters(3, 0), Length.FromMeters(0.001)); // true
ray.Contains(LengthPoint2.FromMeters(-1, 0), Length.FromMeters(0.001)); // false — behind origin
DistanceTo(LengthPoint2)
Returns the shortest distance from point to this ray.
If the nearest point is behind the origin, the distance to the origin is returned.
public Length DistanceTo(LengthPoint2 point)
Parameters
pointLengthPoint2The world-space query point.
Returns
- Length
The shortest distance from the point to the ray.
Examples
var ray = new LengthRay2(LengthPoint2.Origin, Direction2.East);
ray.DistanceTo(LengthPoint2.FromMeters( 3, 4)); // 4 m
ray.DistanceTo(LengthPoint2.FromMeters(-3, 4)); // 5 m (distance to origin)
GetClosestPoint(LengthPoint2)
Returns the point on this ray nearest to point.
Projects the point onto the ray's direction; if the projection is behind the origin
(negative parameter), the origin is returned instead.
public LengthPoint2 GetClosestPoint(LengthPoint2 point)
Parameters
pointLengthPoint2The world-space query point.
Returns
- LengthPoint2
The nearest point on the ray, clamped to the origin if behind it.
Examples
var ray = new LengthRay2(LengthPoint2.Origin, Direction2.East);
ray.GetClosestPoint(LengthPoint2.FromMeters( 3, 4)); // (3, 0)
ray.GetClosestPoint(LengthPoint2.FromMeters(-3, 0)); // (0, 0) — clamped to origin
GetIntersection(LengthRay2)
Returns the intersection point of this ray with other, or
null when they do not intersect in front of both origins.
"In front" means the intersection occurs at a non-negative parameter value along each ray — i.e. the intersection is not behind either origin. Parallel rays and rays whose lines intersect only behind at least one origin both return null.
public LengthPoint2? GetIntersection(LengthRay2 other)
Parameters
otherLengthRay2The other ray to test against.
Returns
- LengthPoint2?
The intersection point, or null if the rays don't meet in front of both origins.
Examples
var a = new LengthRay2(LengthPoint2.Origin, Direction2.FromDegrees(0)); // right
var b = new LengthRay2(LengthPoint2.FromMeters(2, 2), Direction2.FromDegrees(270)); // down
LengthPoint2? pt = a.GetIntersection(b); // (2, 0)
GetPointAtMagnitude(Length)
Returns the point on the ray at the given distance from the origin.
public LengthPoint2 GetPointAtMagnitude(Length magnitude)
Parameters
magnitudeLengthThe distance along the ray from Position. Negative values travel behind the origin, which is technically valid but not typical ray usage.
Returns
Examples
var ray = new LengthRay2(LengthPoint2.FromMeters(1, 0), Direction2.FromDegrees(0));
var pt = ray.GetPointAtMagnitude(Length.FromMeters(3)); // (4, 0)
HasPoint(LengthPoint2, Length)
Returns true when point lies on the ray
within tolerance.
A point is "on the ray" when it is perpendicular-close to the underlying infinite line and its projection parameter is non-negative (i.e. the point is not behind the origin).
public bool HasPoint(LengthPoint2 point, Length tolerance)
Parameters
pointLengthPoint2The query point.
toleranceLengthMaximum perpendicular distance from the ray's line for the point to be considered "on" the ray.
Returns
Examples
var ray = new LengthRay2(LengthPoint2.Origin, Direction2.FromDegrees(0));
bool fwd = ray.HasPoint(LengthPoint2.FromMeters(3, 0), Length.FromMeters(0.001)); // true
bool back = ray.HasPoint(LengthPoint2.FromMeters(-1, 0), Length.FromMeters(0.001)); // false
Intersect(IEnumerable<Capsule2>)
Intersects against all shapes and returns the closest hit, or null if all miss.
public RaycastHit? Intersect(IEnumerable<Capsule2> shapes)
Parameters
shapesIEnumerable<Capsule2>
Returns
Intersect(IEnumerable<Circle2>)
Intersects against all shapes and returns the closest hit, or null if all miss.
public RaycastHit? Intersect(IEnumerable<Circle2> shapes)
Parameters
shapesIEnumerable<Circle2>
Returns
Intersect(IEnumerable<Polygon2>)
Intersects against all shapes and returns the closest hit, or null if all miss.
public RaycastHit? Intersect(IEnumerable<Polygon2> shapes)
Parameters
shapesIEnumerable<Polygon2>
Returns
Exceptions
- InvalidOperationException
Propagated if any polygon in
shapesis not convex.
Intersect(IEnumerable<Rectangle2>)
Intersects against all shapes and returns the closest hit, or null if all miss.
public RaycastHit? Intersect(IEnumerable<Rectangle2> shapes)
Parameters
shapesIEnumerable<Rectangle2>
Returns
Intersect(IEnumerable<Triangle2>)
Intersects against all shapes and returns the closest hit, or null if all miss.
public RaycastHit? Intersect(IEnumerable<Triangle2> shapes)
Parameters
shapesIEnumerable<Triangle2>
Returns
Intersect(Capsule2)
Casts this ray against capsule and returns the hit data, or
null if the ray does not intersect the capsule.
If the ray origin is inside the capsule the method returns the exit hit. The capsule is tested as two semicircular end caps plus two barrel-side segments.
public RaycastHit? Intersect(Capsule2 capsule)
Parameters
capsuleCapsule2The capsule to test against.
Returns
- RaycastHit?
A RaycastHit with the distance, world-space contact point, and outward surface normal, or null if the ray misses.
Intersect(Circle2)
Casts this ray against circle and returns the hit data, or
null if the ray does not intersect the circle.
If the ray origin is inside the circle, the method returns the exit hit — the point where the ray leaves the circle's boundary — with the outward surface normal.
public RaycastHit? Intersect(Circle2 circle)
Parameters
circleCircle2The circle to test against.
Returns
- RaycastHit?
A RaycastHit with the distance, world-space contact point, and outward normal, or null if the ray misses.
Examples
var ray = new LengthRay2(LengthPoint2.FromMeters(-3, 0), Direction2.East);
var circle = new Circle2(LengthPoint2.FromMeters(5, 0), Radius.FromMeters(1));
RaycastHit? hit = ray.Intersect(circle);
// hit.Distance == 7 m, hit.Point == (4, 0), hit.Normal == West (-1, 0)
Intersect(Polygon2)
Casts this ray against polygon and returns the hit data, or
null if the ray does not intersect the polygon.
The polygon must be convex. If it is concave an InvalidOperationException is thrown.
public RaycastHit? Intersect(Polygon2 polygon)
Parameters
polygonPolygon2The convex polygon to test against.
Returns
- RaycastHit?
A RaycastHit with the distance, world-space contact point, and outward face normal, or null if the ray misses.
Exceptions
- InvalidOperationException
Thrown when
polygonis not convex.
Intersect(Rectangle2)
Casts this ray against rect and returns the hit data, or
null if the ray does not intersect the rectangle.
If the ray origin is inside the rectangle the method returns the exit hit.
public RaycastHit? Intersect(Rectangle2 rect)
Parameters
rectRectangle2The rectangle to test against.
Returns
- RaycastHit?
A RaycastHit with the distance, world-space contact point, and outward surface normal, or null if the ray misses.
Examples
var ray = new LengthRay2(LengthPoint2.FromMeters(-3, 0), Direction2.East);
var rect = new Rectangle2(LengthPoint2.FromMeters(5, 0), LengthVector2.FromMeters(4, 2));
RaycastHit? hit = ray.Intersect(rect);
// hit.Distance == 6 m, hit.Point == (3, 0), hit.Normal == West
Intersect(Triangle2)
Casts this ray against triangle and returns the hit data, or
null if the ray does not intersect any edge of the triangle.
If the ray origin is inside the triangle the method returns the exit hit (the edge the ray leaves through).
public RaycastHit? Intersect(Triangle2 triangle)
Parameters
triangleTriangle2The triangle to test against.
Returns
- RaycastHit?
A RaycastHit with the distance, world-space contact point, and outward face normal, or null if the ray misses all three edges.
IntersectAll(IEnumerable<Capsule2>)
Intersects against all shapes and returns all hits ordered by distance ascending.
public IEnumerable<RaycastHit> IntersectAll(IEnumerable<Capsule2> shapes)
Parameters
shapesIEnumerable<Capsule2>
Returns
IntersectAll(IEnumerable<Circle2>)
Intersects against all shapes and returns all hits ordered by distance ascending.
public IEnumerable<RaycastHit> IntersectAll(IEnumerable<Circle2> shapes)
Parameters
shapesIEnumerable<Circle2>
Returns
IntersectAll(IEnumerable<Polygon2>)
Intersects against all shapes and returns all hits ordered by distance ascending.
public IEnumerable<RaycastHit> IntersectAll(IEnumerable<Polygon2> shapes)
Parameters
shapesIEnumerable<Polygon2>
Returns
Exceptions
- InvalidOperationException
Propagated if any polygon in
shapesis not convex.
IntersectAll(IEnumerable<Rectangle2>)
Intersects against all shapes and returns all hits ordered by distance ascending.
public IEnumerable<RaycastHit> IntersectAll(IEnumerable<Rectangle2> shapes)
Parameters
shapesIEnumerable<Rectangle2>
Returns
IntersectAll(IEnumerable<Triangle2>)
Intersects against all shapes and returns all hits ordered by distance ascending.
public IEnumerable<RaycastHit> IntersectAll(IEnumerable<Triangle2> shapes)
Parameters
shapesIEnumerable<Triangle2>
Returns
WithMagnitude(Length)
Converts this ray into a finite LengthSegment2 by capping it at
magnitude from the origin.
public LengthSegment2 WithMagnitude(Length magnitude)
Parameters
magnitudeLengthThe length of the resulting segment.
Returns
- LengthSegment2
A segment from Position to
Position + Direction *.magnitude
Examples
var ray = new LengthRay2(LengthPoint2.Origin, Direction2.FromDegrees(0));
var segment = ray.WithMagnitude(Length.FromMeters(5));
// segment.Start == (0, 0)
// segment.End == (5, 0)