Struct DoubleVector2
A double-precision 2D vector with dimensionless components — the foundation for all direction and unit-vector arithmetic in this library.
Unlike the unit-aware vector types (e.g. LengthVector2, SpeedVector2), DoubleVector2 carries no physical unit. It is used for:
- Unit direction vectors returned by Normalize() and similar methods — these have magnitude 1 and no unit.
- Projections and dot products where a dimensionless coefficient is needed.
- Intermediate results in geometry calculations (e.g. ray directions in
Thunder.UnitsNET.Vectors.Geometry).
Positive X points right; positive Y points up (standard mathematical convention).
public readonly record struct DoubleVector2 : IEquatable<DoubleVector2>
- Implements
- Inherited Members
- Extension Methods
Constructors
DoubleVector2(double, double)
A double-precision 2D vector with dimensionless components — the foundation for all direction and unit-vector arithmetic in this library.
Unlike the unit-aware vector types (e.g. LengthVector2, SpeedVector2), DoubleVector2 carries no physical unit. It is used for:
- Unit direction vectors returned by Normalize() and similar methods — these have magnitude 1 and no unit.
- Projections and dot products where a dimensionless coefficient is needed.
- Intermediate results in geometry calculations (e.g. ray directions in
Thunder.UnitsNET.Vectors.Geometry).
Positive X points right; positive Y points up (standard mathematical convention).
public DoubleVector2(double X, double Y)
Parameters
Properties
Magnitude
Returns the Euclidean magnitude (length) of this vector.
Computed as √(X² + Y²). For a unit vector the result is 1. For a zero vector the result is 0.
public double Magnitude { get; }
Property Value
Examples
var v = new DoubleVector2(3, 4);
double len = v.Magnitude; // 5.0 — classic 3-4-5 right triangle
X
public double X { get; init; }
Property Value
Y
public double Y { get; init; }
Property Value
Zero
The zero vector (0, 0).
public static DoubleVector2 Zero { get; }
Property Value
Methods
Abs()
Returns a vector with each component replaced by its absolute value.
Negative components become their positive equivalent; non-negative components are unchanged. This is a per-component operation — the result is not the magnitude of the vector.
public DoubleVector2 Abs()
Returns
- DoubleVector2
A DoubleVector2 with non-negative components.
Examples
var v = new DoubleVector2(-3.0, 4.0);
var positive = v.Abs(); // => new DoubleVector2(3.0, 4.0)
Add(DoubleVector2)
Adds two vectors component-wise.
public DoubleVector2 Add(DoubleVector2 other)
Parameters
otherDoubleVector2The vector to add.
Returns
- DoubleVector2
The component-wise sum.
ApproximatelyEquals(DoubleVector2, double)
Returns true if each component of this vector is within
tolerance of the corresponding component of other.
The comparison is per-component: both X and Y must be within tolerance
independently.
public bool ApproximatelyEquals(DoubleVector2 other, double tolerance)
Parameters
otherDoubleVector2The vector to compare against.
tolerancedoubleThe maximum allowed difference per component (inclusive).
Returns
Examples
var a = new DoubleVector2(1.0, 2.0);
var b = new DoubleVector2(1.0005, 2.0005);
bool close = a.ApproximatelyEquals(b, 0.001); // => true
Clamp(DoubleVector2, DoubleVector2)
Returns a vector with each component clamped to the range [min, max].
Each component is clamped independently: if a component is below min's
corresponding component it becomes that minimum; if above max's component
it becomes that maximum; otherwise it is unchanged.
public DoubleVector2 Clamp(DoubleVector2 min, DoubleVector2 max)
Parameters
minDoubleVector2The lower bound vector (inclusive, per component).
maxDoubleVector2The upper bound vector (inclusive, per component).
Returns
- DoubleVector2
A DoubleVector2 with each component in [min, max].
Examples
var v = new DoubleVector2(-1.0, 5.0);
var min = new DoubleVector2(0.0, 0.0);
var max = new DoubleVector2(3.0, 3.0);
var bounded = v.Clamp(min, max); // => new DoubleVector2(0.0, 3.0)
CrossProduct(DoubleVector2)
Returns the 2D cross product (also called the perpendicular dot product or
signed area) of this vector with other: X·other.Y − Y·other.X.
The result is the signed area of the parallelogram spanned by the two vectors:
- Positive when
otheris counter-clockwise (CCW) from this vector. - Negative when
otheris clockwise (CW). - Zero when the vectors are parallel or anti-parallel.
Unlike the 3D cross product, the 2D version produces a scalar (the Z component of the 3D cross product, with X = Y = 0 assumed).
public double CrossProduct(DoubleVector2 other)
Parameters
otherDoubleVector2The other vector.
Returns
- double
The scalar cross product (this.X × other.Y − this.Y × other.X).
Examples
var right = new DoubleVector2(1, 0);
var up = new DoubleVector2(0, 1);
double c1 = right.CrossProduct(up); // +1.0 — up is CCW from right
double c2 = up.CrossProduct(right); // −1.0 — right is CW from up
Divide(double)
Divides the vector by a scalar divisor.
public DoubleVector2 Divide(double scalar)
Parameters
scalardoubleThe scalar divisor.
Returns
- DoubleVector2
The divided vector.
Dot(DoubleVector2)
Returns the scalar dot product of this vector with other.
The dot product equals |a|·|b|·cos(θ), where θ is the angle between the two vectors. It is:
- Positive when the vectors point in roughly the same direction (θ < 90°).
- Zero when the vectors are perpendicular (θ = 90°).
- Negative when they point in roughly opposite directions (θ > 90°).
For unit vectors the dot product equals cos(θ) directly, making it useful for fast angle-comparisons without calling Acos(double).
public double Dot(DoubleVector2 other)
Parameters
otherDoubleVector2The other vector.
Returns
- double
The scalar dot product.
Examples
var right = new DoubleVector2(1, 0);
var up = new DoubleVector2(0, 1);
double d1 = right.Dot(up); // 0.0 — perpendicular
double d2 = right.Dot(right); // 1.0 — same direction, both unit vectors
FromAngle(Angle)
Creates a unit vector pointing in the direction of angle
measured from the positive X-axis, counter-clockwise.
The result always has magnitude 1: X = cos(angle), Y = sin(angle). This is the standard way to convert a heading angle into a direction vector.
public static DoubleVector2 FromAngle(Angle angle)
Parameters
angleAngleThe direction angle. 0° points right (+X). 90° points up (+Y). 180° points left. 270° points down (−Y). Counter-clockwise is positive.
Returns
- DoubleVector2
A unit DoubleVector2 pointing in the specified direction.
Examples
var right = DoubleVector2.FromAngle(Angle.FromDegrees(0)); // (1, 0)
var up = DoubleVector2.FromAngle(Angle.FromDegrees(90)); // (0, 1)
var diag = DoubleVector2.FromAngle(Angle.FromDegrees(45)); // (√2/2, √2/2) ≈ (0.707, 0.707)
Lerp(DoubleVector2, DoubleVector2, double)
Linearly interpolates between two vectors.
The result at t = 0 is a; at t = 1 it is
b. Values of t outside [0, 1] extrapolate beyond the
endpoints — use LerpClamped(DoubleVector2, DoubleVector2, double) if you need the result bounded to the segment
between a and b.
public static DoubleVector2 Lerp(DoubleVector2 a, DoubleVector2 b, double t)
Parameters
aDoubleVector2The start vector (
t= 0).bDoubleVector2The end vector (
t= 1).tdoubleThe interpolation parameter. Values outside [0, 1] extrapolate.
Returns
- DoubleVector2
The interpolated DoubleVector2.
Examples
var a = new DoubleVector2(0.0, 0.0);
var b = new DoubleVector2(2.0, 4.0);
var mid = DoubleVector2.Lerp(a, b, 0.5); // => new DoubleVector2(1.0, 2.0)
var past = DoubleVector2.Lerp(a, b, 1.5); // => new DoubleVector2(3.0, 6.0)
LerpClamped(DoubleVector2, DoubleVector2, double)
Linearly interpolates between two vectors, with t clamped to [0, 1].
Equivalent to Lerp(DoubleVector2, DoubleVector2, double) but the result is always between a and
b: passing t below 0 returns a;
passing t above 1 returns b.
public static DoubleVector2 LerpClamped(DoubleVector2 a, DoubleVector2 b, double t)
Parameters
aDoubleVector2The start vector (
t= 0).bDoubleVector2The end vector (
t= 1).tdoubleThe interpolation parameter, clamped to [0, 1].
Returns
- DoubleVector2
The interpolated DoubleVector2, always between
aandb.
Examples
var a = new DoubleVector2(0.0, 0.0);
var b = new DoubleVector2(2.0, 4.0);
var clamped = DoubleVector2.LerpClamped(a, b, 1.5); // => new DoubleVector2(2.0, 4.0)
var back = DoubleVector2.LerpClamped(a, b, -0.5); // => new DoubleVector2(0.0, 0.0)
Multiply(double)
Scales the vector by a scalar factor.
public DoubleVector2 Multiply(double scalar)
Parameters
scalardoubleThe scalar factor.
Returns
- DoubleVector2
The scaled vector.
Negate()
Negates both components.
public DoubleVector2 Negate()
Returns
- DoubleVector2
A vector with both components negated.
Normalize()
Returns a unit vector (magnitude = 1) in the same direction as this vector. Returns Zero if this vector has zero magnitude.
Normalising converts any non-zero vector into a pure direction, stripping the magnitude. This is useful when you need to express "which way" without "how far" — for example, deriving a movement direction from a displacement before multiplying by a desired speed.
public DoubleVector2 Normalize()
Returns
- DoubleVector2
A unit-length DoubleVector2, or Zero for a zero vector.
Examples
var v = new DoubleVector2(3, 4);
var unit = v.Normalize(); // (0.6, 0.8) — magnitude is exactly 1.0
Subtract(DoubleVector2)
Subtracts two vectors component-wise.
public DoubleVector2 Subtract(DoubleVector2 other)
Parameters
otherDoubleVector2The vector to subtract.
Returns
- DoubleVector2
The component-wise difference.
ToString()
Returns the vector formatted to 2 decimal places.
public override string ToString()
Returns
ToString(string)
Returns the vector formatted using format for each component.
public string ToString(string format)
Parameters
formatstringA numeric format string applied to each component.
Returns
- string
A comma-separated string of the two components.
Operators
operator +(DoubleVector2, DoubleVector2)
Adds two vectors component-wise.
public static DoubleVector2 operator +(DoubleVector2 left, DoubleVector2 right)
Parameters
leftDoubleVector2The left operand.
rightDoubleVector2The right operand.
Returns
- DoubleVector2
The component-wise sum.
operator /(DoubleVector2, double)
Divides the vector by a scalar divisor.
public static DoubleVector2 operator /(DoubleVector2 left, double scalar)
Parameters
leftDoubleVector2The vector to scale.
scalardoubleThe scalar divisor.
Returns
- DoubleVector2
The divided vector.
operator *(double, DoubleVector2)
Scales the vector by a scalar factor. Operands may be supplied in either order.
public static DoubleVector2 operator *(double scalar, DoubleVector2 right)
Parameters
scalardoubleThe scalar factor.
rightDoubleVector2The vector to scale.
Returns
- DoubleVector2
The scaled vector.
operator *(DoubleVector2, double)
Scales the vector by a scalar factor.
public static DoubleVector2 operator *(DoubleVector2 left, double scalar)
Parameters
leftDoubleVector2The vector to scale.
scalardoubleThe scalar factor.
Returns
- DoubleVector2
The scaled vector.
operator -(DoubleVector2, DoubleVector2)
Subtracts two vectors component-wise.
public static DoubleVector2 operator -(DoubleVector2 left, DoubleVector2 right)
Parameters
leftDoubleVector2The left operand.
rightDoubleVector2The right operand.
Returns
- DoubleVector2
The component-wise difference.
operator -(DoubleVector2)
Negates both components.
public static DoubleVector2 operator -(DoubleVector2 value)
Parameters
valueDoubleVector2The vector to negate.
Returns
- DoubleVector2
A vector with both components negated.