Class Direction2Extensions
Extension methods for Direction2 that provide rotation helpers, angle measurements, and approximate-equality comparisons.
These are defined as extension methods rather than instance methods so they can be added to without modifying the core Direction2 struct.
public static class Direction2Extensions
- Inheritance
-
Direction2Extensions
- Inherited Members
Methods
AngleBetween(Direction2, Direction2)
Returns the smallest angle between a and b,
always in the range [0°, 180°].
This is the unsigned (non-directional) angle — it does not tell you whether
b is clockwise or counter-clockwise from a.
Use SignedAngleTo(Direction2, Direction2) when rotation direction matters.
public static Angle AngleBetween(this Direction2 a, Direction2 b)
Parameters
aDirection2The first direction.
bDirection2The second direction.
Returns
- Angle
The smallest angle between the two directions, in [0°, 180°]. The result is the same regardless of which direction is
aorb.
Examples
var right = Direction2.FromDegrees(0);
var up = Direction2.FromDegrees(90);
Angle between = right.AngleBetween(up); // 90°
ApproximatelyEquals(Direction2, Direction2, Angle)
Returns true when a and b
are within tolerance of each other, handling the 0°/360° wrap.
Use this in game loops where floating-point drift means two directions that should be equal are not exactly equal. For example, a direction that has been rotated back to its starting point may not be exactly equal due to accumulated error.
public static bool ApproximatelyEquals(this Direction2 a, Direction2 b, Angle tolerance)
Parameters
aDirection2The first direction.
bDirection2The second direction.
toleranceAngleThe maximum angular difference allowed. Must be non-negative.
Returns
Examples
var a = Direction2.FromDegrees(0.0005);
var b = Direction2.FromDegrees(359.9995);
bool equal = a.ApproximatelyEquals(b, Angle.FromDegrees(0.001)); // true
ApproximatelyEqualsOrInverse(Direction2, Direction2, Angle)
Returns true when a and b
are approximately equal OR approximately opposite (anti-parallel) within
tolerance.
Useful when you need to check whether two directions represent the same undirected line — for example, checking whether a surface normal is aligned with a movement direction, regardless of which way each is pointing.
public static bool ApproximatelyEqualsOrInverse(this Direction2 a, Direction2 b, Angle tolerance)
Parameters
aDirection2The first direction.
bDirection2The second direction to compare against.
toleranceAngleThe maximum angular difference allowed for each comparison. Must be non-negative.
Returns
Examples
var a = Direction2.FromDegrees(0);
var b = Direction2.FromDegrees(180);
bool same = a.ApproximatelyEqualsOrInverse(b, Angle.FromDegrees(0.001)); // true
BidirectionalAngleBetween(Direction2, Direction2)
Returns the smallest angle between two directions when their orientation does not matter — i.e., the angle between the undirected lines they represent.
Two anti-parallel directions (e.g. 0° and 180°) represent the same undirected
line, so BidirectionalAngleBetween returns 0°. The result is always in
[0°, 90°].
public static Angle BidirectionalAngleBetween(this Direction2 a, Direction2 b)
Parameters
aDirection2The first direction.
bDirection2The second direction.
Returns
- Angle
The smallest angle between the two undirected lines, in [0°, 90°].
Examples
var right = Direction2.FromDegrees(0);
var left = Direction2.FromDegrees(180);
Angle angle = right.BidirectionalAngleBetween(left); // 0° — same line
Lerp(Direction2, Direction2, double)
Interpolates between two directions along the shortest arc (≤ 180°).
At t=0 the result is a; at
t=1 the result is b. The rotation always
takes the shorter of the two possible arcs. When the two directions are exactly
anti-parallel (180° apart) the CCW arc is taken.
public static Direction2 Lerp(Direction2 a, Direction2 b, double t)
Parameters
aDirection2The start direction.
bDirection2The end direction.
tdoubleInterpolation factor, typically in [0, 1].
Returns
- Direction2
A Direction2 interpolated from
atob.
Examples
var start = Direction2.FromDegrees(350);
var end = Direction2.FromDegrees(10);
var mid = Direction2Extensions.Lerp(start, end, 0.5); // 0° — short 20° arc
LerpRaw(Direction2, Direction2, double)
Interpolates between two directions using raw angle arithmetic (no shortest-path logic).
Unlike Lerp(Direction2, Direction2, double), this method simply blends the raw degree values of
a and b without snapping to the shorter arc.
For example, interpolating from 350° to 10° at t=0.5 gives 180° (the long way round),
not 0°.
Use Lerp(Direction2, Direction2, double) for natural shortest-path rotation. Use this method only when you explicitly want raw linear angle blending regardless of arc length.
public static Direction2 LerpRaw(Direction2 a, Direction2 b, double t)
Parameters
aDirection2The start direction.
bDirection2The end direction.
tdoubleInterpolation factor, typically in [0, 1].
Returns
- Direction2
A Direction2 whose angle is the raw linear blend of
aandb.
Examples
var start = Direction2.FromDegrees(350);
var end = Direction2.FromDegrees(10);
var mid = Direction2Extensions.LerpRaw(start, end, 0.5); // 180° — raw average
RotatePerpendicularly(Direction2)
Returns a new Direction2 rotated 90° counter-clockwise from
source. Equivalent to source.Rotate(Angle.FromDegrees(90)).
A 90° CCW rotation is the standard way to get the "left perpendicular" of a direction, which is useful for computing normals, strafing vectors, and determining which side of a line a point is on.
public static Direction2 RotatePerpendicularly(this Direction2 source)
Parameters
sourceDirection2The direction to rotate.
Returns
- Direction2
A Direction2 perpendicular (CCW) to
source.
Examples
var forward = Direction2.FromDegrees(0);
var left = forward.RotatePerpendicularly(); // 90°
RotateTowards(Direction2, Angle, Direction2)
Rotates source towards target by at most
maxAmount, taking the shortest arc and never overshooting.
This is the "steering" primitive used in game AI and animation: you know where you want to face and how fast you can turn, and you want the new facing direction after one update step. Key behaviours:
-
If the angular distance to
targetis ≤maxAmount, the result is exactlytarget(no overshoot). -
The rotation always takes the shorter of the two possible arcs (the arc that covers
less than or equal to 180°). When
sourceandtargetare exactly 180° apart, the convention is counter-clockwise. -
A
maxAmountof 0° returnssourceunchanged.
public static Direction2 RotateTowards(this Direction2 source, Angle maxAmount, Direction2 target)
Parameters
sourceDirection2The current direction.
maxAmountAngleThe maximum angle to rotate. Must be non-negative.
targetDirection2The desired direction to rotate towards.
Returns
- Direction2
A Direction2 at most
maxAmountaway fromsource, rotated towardstarget.
Examples
// Turn at most 10° per frame towards North (90°), starting from East (0°)
var facing = Direction2.East;
var target = Direction2.North;
facing = facing.RotateTowards(Angle.FromDegrees(10), target);
// facing is now 10° (turned 10° CCW towards North)
// Snaps when close enough
var almost = Direction2.FromDegrees(85);
var result = almost.RotateTowards(Angle.FromDegrees(30), target);
// result is exactly 90° (not 115°)
SignedAngleTo(Direction2, Direction2)
Returns the signed angle from from to to,
in the range (−180°, 180°].
A positive result means to is counter-clockwise (CCW) from
from; a negative result means clockwise (CW). A result of
exactly ±180° is returned as +180°.
public static Angle SignedAngleTo(this Direction2 from, Direction2 to)
Parameters
fromDirection2The starting direction.
toDirection2The target direction to rotate towards.
Returns
- Angle
The signed angle in (−180°, 180°]: positive = CCW, negative = CW.
Examples
var right = Direction2.FromDegrees(0);
var up = Direction2.FromDegrees(90);
Angle angle = right.SignedAngleTo(up); // +90° (CCW)