Struct DoubleVector3
A double-precision 3D vector with dimensionless components — the foundation for all direction and unit-vector arithmetic in three dimensions.
Unlike the unit-aware vector types (e.g. LengthVector3, SpeedVector3), DoubleVector3 carries no physical unit. It is used for:
- Unit direction vectors returned by Normalize() and similar methods — these have magnitude 1 and no unit.
- Surface normals, ray directions, and other pure geometric directions in 3D rendering and physics engines.
- Intermediate results in 3D geometry calculations such as cross products, projections, and rotation axes.
Positive X points right, positive Y points up, and positive Z points toward the viewer (right-handed coordinate system). Cross products follow the right-hand rule.
public readonly record struct DoubleVector3 : IEquatable<DoubleVector3>
- Implements
- Inherited Members
- Extension Methods
Constructors
DoubleVector3(double, double, double)
A double-precision 3D vector with dimensionless components — the foundation for all direction and unit-vector arithmetic in three dimensions.
Unlike the unit-aware vector types (e.g. LengthVector3, SpeedVector3), DoubleVector3 carries no physical unit. It is used for:
- Unit direction vectors returned by Normalize() and similar methods — these have magnitude 1 and no unit.
- Surface normals, ray directions, and other pure geometric directions in 3D rendering and physics engines.
- Intermediate results in 3D geometry calculations such as cross products, projections, and rotation axes.
Positive X points right, positive Y points up, and positive Z points toward the viewer (right-handed coordinate system). Cross products follow the right-hand rule.
public DoubleVector3(double X, double Y, double Z)
Parameters
Properties
Magnitude
Returns the Euclidean magnitude (length) of this vector.
Computed as √(X² + Y² + Z²). For a unit vector the result is 1. For a zero vector the result is 0. A magnitude of 1 means the vector is a pure direction with no scaling.
public double Magnitude { get; }
Property Value
- double
The Euclidean length of this vector.
Examples
var v = new DoubleVector3(1, 2, 2);
double len = v.Magnitude; // 3.0 — because √(1+4+4) = 3
X
public double X { get; init; }
Property Value
Y
public double Y { get; init; }
Property Value
Z
public double Z { get; init; }
Property Value
Zero
The zero vector (0, 0, 0).
public static DoubleVector3 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 DoubleVector3 Abs()
Returns
- DoubleVector3
A DoubleVector3 with non-negative components.
Examples
var v = new DoubleVector3(-3.0, 4.0, -5.0);
var positive = v.Abs(); // => new DoubleVector3(3.0, 4.0, 5.0)
Add(DoubleVector3)
Adds two vectors component-wise.
public DoubleVector3 Add(DoubleVector3 other)
Parameters
otherDoubleVector3The vector to add.
Returns
- DoubleVector3
The component-wise sum.
ApproximatelyEquals(DoubleVector3, double)
Returns true if each component of this vector is within
tolerance of the corresponding component of other.
The comparison is per-component: X, Y, and Z must each be within tolerance
independently.
public bool ApproximatelyEquals(DoubleVector3 other, double tolerance)
Parameters
otherDoubleVector3The vector to compare against.
tolerancedoubleThe maximum allowed difference per component (inclusive).
Returns
Examples
var a = new DoubleVector3(1.0, 2.0, 3.0);
var b = new DoubleVector3(1.0005, 2.0005, 3.0005);
bool close = a.ApproximatelyEquals(b, 0.001); // => true
Clamp(DoubleVector3, DoubleVector3)
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 DoubleVector3 Clamp(DoubleVector3 min, DoubleVector3 max)
Parameters
minDoubleVector3The lower bound vector (inclusive, per component).
maxDoubleVector3The upper bound vector (inclusive, per component).
Returns
- DoubleVector3
A DoubleVector3 with each component in [min, max].
Examples
var v = new DoubleVector3(-1.0, 5.0, 2.0);
var min = new DoubleVector3(0.0, 0.0, 0.0);
var max = new DoubleVector3(3.0, 3.0, 3.0);
var bounded = v.Clamp(min, max); // => new DoubleVector3(0.0, 3.0, 2.0)
CrossProduct(DoubleVector3)
Returns the 3D cross product of this vector with other,
producing a new vector perpendicular to both.
The cross product follows the right-hand rule: point your fingers in the direction
of this vector, curl them toward other, and your thumb points in
the direction of the result. Key properties:
- The result is perpendicular to both input vectors.
- Its magnitude equals |a|·|b|·sin(θ), the area of the parallelogram spanned by the two vectors.
- For parallel or anti-parallel vectors (θ = 0° or 180°), the result is the zero vector.
- The sign (direction) reverses if you swap the operands: b × a = −(a × b).
Common uses include computing surface normals, finding a rotation axis, calculating torque, and testing whether two vectors are parallel.
public DoubleVector3 CrossProduct(DoubleVector3 other)
Parameters
otherDoubleVector3The second vector (right operand of the cross product).
Returns
- DoubleVector3
A DoubleVector3 perpendicular to both input vectors (right-hand rule).
Examples
var right = new DoubleVector3(1, 0, 0); // +X
var forward = new DoubleVector3(0, 0, 1); // +Z
// right × forward = down (−Y) by the right-hand rule
DoubleVector3 normal = right.CrossProduct(forward); // (0, −1, 0)
// Use to compute a surface normal from two edge vectors of a triangle
var edge1 = new DoubleVector3(1, 0, 0);
var edge2 = new DoubleVector3(0, 1, 0);
DoubleVector3 surfaceNormal = edge1.CrossProduct(edge2).Normalize(); // (0, 0, 1)
Divide(double)
Divides the vector by a scalar divisor.
public DoubleVector3 Divide(double scalar)
Parameters
scalardoubleThe scalar divisor.
Returns
- DoubleVector3
The divided vector.
Dot(DoubleVector3)
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(DoubleVector3 other)
Parameters
otherDoubleVector3The other vector.
Returns
- double
The scalar dot product.
Examples
var forward = new DoubleVector3(0, 0, 1);
var up = new DoubleVector3(0, 1, 0);
double d1 = forward.Dot(up); // 0.0 — perpendicular
double d2 = forward.Dot(forward); // 1.0 — same direction, both unit vectors
Lerp(DoubleVector3, DoubleVector3, 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(DoubleVector3, DoubleVector3, double) if you need the result bounded to the segment
between a and b.
public static DoubleVector3 Lerp(DoubleVector3 a, DoubleVector3 b, double t)
Parameters
aDoubleVector3The start vector (
t= 0).bDoubleVector3The end vector (
t= 1).tdoubleThe interpolation parameter. Values outside [0, 1] extrapolate.
Returns
- DoubleVector3
The interpolated DoubleVector3.
Examples
var a = new DoubleVector3(0.0, 0.0, 0.0);
var b = new DoubleVector3(2.0, 4.0, 6.0);
var mid = DoubleVector3.Lerp(a, b, 0.5); // => new DoubleVector3(1.0, 2.0, 3.0)
var past = DoubleVector3.Lerp(a, b, 1.5); // => new DoubleVector3(3.0, 6.0, 9.0)
LerpClamped(DoubleVector3, DoubleVector3, double)
Linearly interpolates between two vectors, with t clamped to [0, 1].
Equivalent to Lerp(DoubleVector3, DoubleVector3, double) but the result is always between a and
b: passing t below 0 returns a;
passing t above 1 returns b.
public static DoubleVector3 LerpClamped(DoubleVector3 a, DoubleVector3 b, double t)
Parameters
aDoubleVector3The start vector (
t= 0).bDoubleVector3The end vector (
t= 1).tdoubleThe interpolation parameter, clamped to [0, 1].
Returns
- DoubleVector3
The interpolated DoubleVector3, always between
aandb.
Examples
var a = new DoubleVector3(0.0, 0.0, 0.0);
var b = new DoubleVector3(2.0, 4.0, 6.0);
var clamped = DoubleVector3.LerpClamped(a, b, 1.5); // => new DoubleVector3(2.0, 4.0, 6.0)
var back = DoubleVector3.LerpClamped(a, b, -0.5); // => new DoubleVector3(0.0, 0.0, 0.0)
Multiply(double)
Scales the vector by a scalar factor.
public DoubleVector3 Multiply(double scalar)
Parameters
scalardoubleThe scalar factor.
Returns
- DoubleVector3
The scaled vector.
Negate()
Negates all components.
public DoubleVector3 Negate()
Returns
- DoubleVector3
A vector with all 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. The result always satisfies result.Magnitude == 1.0 (within
floating-point precision). A normalised vector is also called a unit vector or
direction vector. 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, or computing a surface normal.
public DoubleVector3 Normalize()
Returns
- DoubleVector3
A unit-length DoubleVector3, or Zero for a zero vector.
Examples
var v = new DoubleVector3(1, 2, 2);
var unit = v.Normalize(); // ≈ (0.333, 0.667, 0.667) — magnitude is exactly 1.0
var direction = new DoubleVector3(3, 0, 4).Normalize(); // ≈ (0.6, 0, 0.8) — magnitude 1
Subtract(DoubleVector3)
Subtracts two vectors component-wise.
public DoubleVector3 Subtract(DoubleVector3 other)
Parameters
otherDoubleVector3The vector to subtract.
Returns
- DoubleVector3
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 three components.
Operators
operator +(DoubleVector3, DoubleVector3)
Adds two vectors component-wise.
public static DoubleVector3 operator +(DoubleVector3 left, DoubleVector3 right)
Parameters
leftDoubleVector3The left operand.
rightDoubleVector3The right operand.
Returns
- DoubleVector3
The component-wise sum.
operator /(DoubleVector3, double)
Divides the vector by a scalar divisor.
public static DoubleVector3 operator /(DoubleVector3 left, double scalar)
Parameters
leftDoubleVector3The vector to scale.
scalardoubleThe scalar divisor.
Returns
- DoubleVector3
The divided vector.
operator *(double, DoubleVector3)
Scales the vector by a scalar factor. Operands may be supplied in either order.
public static DoubleVector3 operator *(double scalar, DoubleVector3 right)
Parameters
scalardoubleThe scalar factor.
rightDoubleVector3The vector to scale.
Returns
- DoubleVector3
The scaled vector.
operator *(DoubleVector3, double)
Scales the vector by a scalar factor.
public static DoubleVector3 operator *(DoubleVector3 left, double scalar)
Parameters
leftDoubleVector3The vector to scale.
scalardoubleThe scalar factor.
Returns
- DoubleVector3
The scaled vector.
operator -(DoubleVector3, DoubleVector3)
Subtracts two vectors component-wise.
public static DoubleVector3 operator -(DoubleVector3 left, DoubleVector3 right)
Parameters
leftDoubleVector3The left operand.
rightDoubleVector3The right operand.
Returns
- DoubleVector3
The component-wise difference.
operator -(DoubleVector3)
Negates all components.
public static DoubleVector3 operator -(DoubleVector3 value)
Parameters
valueDoubleVector3The vector to negate.
Returns
- DoubleVector3
A vector with all components negated.