#include <vector.h>
template<typename T, std::size_t Dim>
Vec class
Template class to represent a vector/coordinate.
Contents
Any dimension can be accessed via random access, i.e. operator[]
, or via its publicly exposed val
array member.
2D vectors additionally provide access via Width
/Height
. Thus, using them to hold 2D dimensions feels lexically correct.
Public types
- using value_type = T
- using index_type = std::size_t
Public static variables
- static std::size_t ndim constexpr
Public static functions
Constructors, destructors, conversion operators
- Vec() noexcept
- Default constructor initializes all fields with 0.
-
template<typename Tp = T>Vec(typename std::enable_if<(Dim==2), Tp>::type x, Tp y) noexcept
- Convenience (x, y) constructor for 2D vector.
-
template<typename Tp = T>Vec(typename std::enable_if<(Dim==3), Tp>::type x, Tp y, Tp z) noexcept
- Convenience (x, y, z) constructor for 3D vector.
-
template<typename Tp = T>Vec(typename std::enable_if<(Dim==4), Tp>::type x, Tp y, Tp z, Tp w) noexcept
- Convenience (x, y, z, w) constructor for 4D vector.
- Vec(std::initializer_list<T> values)
- Constructor accepting an
initializer_list
with either 0 orDim
entries. - ~Vec() defaulted
- Destructor.
- Vec(const Vec<T, Dim>& other) noexcept
- Copy constructor.
- Vec(Vec<T, Dim>&& other) noexcept
- Move constructor.
-
template<typename TargetType>operator Vec<TargetType, Dim>() const explicit
- Explicit cast.
Public functions
- auto operator=(const Vec<T, Dim>& other) -> Vec<T, Dim>& noexcept
- Assignment operator.
- auto operator=(Vec<T, Dim>&& other) -> Vec<T, Dim>& noexcept
- Move assignment operator.
- auto ToDouble() const -> Vec<double, Dim>
- Convenience conversion to double precision.
- auto ToInteger() const -> Vec<int32_t, Dim>
- Convenience conversion (truncation) to an integer vector.
- auto Homogeneous() const -> Vec<T, Dim+1> constexpr
- Returns the homogeneous representation of this vector, i.e. the vector has an additional dimension which is set to 1.
- auto operator[](std::size_t idx) -> T&
- Supports array-like mutable access.
- auto operator[](int idx) -> T&
- Array-like mutable access, which supports negative indexing. For example, vec[-1] == vec[Dim - 1].
- auto operator[](std::size_t idx) const -> const T&
- auto operator[](int idx) const -> const T&
- Array-like non-mutable access, which supports negative indexing. For example, vec[-1] == vec[Dim - 1].
- auto X() const -> const T& noexcept
-
template<typename Tp = T>auto Y() const -> const std::enable_if<(Dim> 1), Tp>::type& noexcept
-
template<typename Tp = T>auto Width() const -> const std::enable_if<(Dim==2), Tp>::type& noexcept
-
template<typename Tp = T>auto Height() const -> const std::enable_if<(Dim==2), Tp>::type& noexcept
-
template<typename Tp = T>auto Z() const -> const std::enable_if<(Dim> 2), Tp>::type& noexcept
-
template<typename Tp = T>auto W() const -> const std::enable_if<(Dim> 3), Tp>::type& noexcept
- auto X() -> T& noexcept
-
template<typename Tp = T>auto Y() -> std::enable_if<(Dim> 1), Tp>::type& noexcept
-
template<typename Tp = T>auto Width() -> std::enable_if<(Dim==2), Tp>::type& noexcept
-
template<typename Tp = T>auto Height() -> std::enable_if<(Dim==2), Tp>::type& noexcept
-
template<typename Tp = T>auto Z() -> std::enable_if<(Dim> 2), Tp>::type& noexcept
-
template<typename Tp = T>auto W() -> std::enable_if<(Dim> 3), Tp>::type& noexcept
- void SetX(T x) noexcept
-
template<typename Tp = T>void SetY(typename std::enable_if<(Dim> 1), Tp>::type y) noexcept
-
template<typename Tp = T>void SetWidth(typename std::enable_if<(Dim==2), Tp>::type width) noexcept
-
template<typename Tp = T>void SetHeight(typename std::enable_if<(Dim==2), Tp>::type height) noexcept
-
template<typename Tp = T>void SetZ(typename std::enable_if<(Dim> 2), Tp>::type z) noexcept
-
template<typename Tp = T>void SetW(typename std::enable_if<(Dim> 3), Tp>::type w) noexcept
-
template<typename Tp = T>auto IsClose(const Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>& other, Tp relative_tolerance, Tp absolute_tolerance) const -> bool
- "Almost equal" check for vectors with floating point value type.
-
template<typename Tp = T>auto IsEqual(const Vec<typename std::enable_if<std::is_integral<Tp>::value, Tp>::type, Dim>& other) const -> bool
- Vectors with integral value type can be compared for equality.
- auto AddVector(const Vec<T, Dim>& rhs) -> Vec<T, Dim>&
- Performs element-wise addition and returns the modified instance.
- auto operator+=(const Vec<T, Dim>& rhs) -> Vec<T, Dim>&
- Overloaded
vec1 + vec2
, seeAddVector
. - auto AddScalar(T value) -> Vec<T, Dim>&
- Adds the scalar to each dimension and returns the modified instance.
- auto operator+=(T value) -> Vec<T, Dim>&
- Overloaded
vec += scalar
, seeAddScalar
. - auto SubtractVector(const Vec<T, Dim>& rhs) -> Vec<T, Dim>&
- Performs element-wise subtraction and returns the modified instance.
- auto operator-=(const Vec<T, Dim>& rhs) -> Vec<T, Dim>&
- Overloaded
vec1 -= vec2
, seeSubtractVector
. - auto SubtractScalar(T value) -> Vec<T, Dim>&
- Subtracts
value
from each dimension and returns the modified instance. - auto operator-=(T value) -> Vec<T, Dim>&
- Overloaded
vec -= scalar
, seeSubtractScalar
. - auto MultiplyScalar(T scale) -> Vec<T, Dim>&
- Multiplies each dimension by the given scalar and returns the modified instance.
- auto operator*=(T scale) -> Vec<T, Dim>&
- Overloaded
vec *= scalar
, seeMultiplyScalar
. - auto MultiplyVector(const Vec<T, Dim>& other) -> Vec<T, Dim>&
- Performs element-wise multiplication and returns the modified instance.
- auto operator*=(const Vec<T, Dim>& other) -> Vec<T, Dim>&
- Overloaded
vec1 *= vec2
, seeMultiplyVector
. -
template<typename Tp = T>auto DivideScalar(Tp divisor) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>&
- Divides each element by the given scalar and returns the modified instance. Note that division is only supported for floating point types. Use ToDouble() to obtain a casted copy of this vector before division.
-
template<typename Tp = T>auto operator/=(double divisor) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>&
- Overloaded for convenience, see
DivideScalar
. Only supported for floating point-based vector specializations. Use ToDouble() to convert integral vectors before division. -
template<typename Tp = T>auto DivideVector(const Vec<Tp, Dim>& divisor) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>&
- Performs element-wise division and returns the modified instance. Only supported for floating point-based vector specializations. Use ToDouble() to convert integral vectors before division.
-
template<typename Tp = T>auto operator/=(const Vec<Tp, Dim>& divisor) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>&
- Overloaded element-wise division, see
DivideVector
. Only supported for floating point-based vector specializations. - auto Negate() -> Vec<T, Dim>&
- Inverts (i.e. negates) each dimension.
- auto operator-() const -> Vec<T, Dim>
- Returns a copy of this vector where each dimension is negated. Use
Negate
to explicitly negate this instance. - auto Dot(const Vec<T, Dim>& other) const -> T
- Computes the dot product.
-
template<typename Tp = T>auto Determinant(const Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>& other) const -> Tp
- Returns the determinant of the two 2d vectors, i.e. the "2d cross product".
-
template<typename Tp = T>auto Cross(const Vec<T, Dim>& other) const -> Vec<typename std::enable_if<(Dim==3), Tp>::type, Dim>
- Returns the 3D vector cross product.
- auto LengthSquared() const -> double
- Returns the squared vector's length.
- auto Length() const -> double
- Returns the vector's length.
- auto DirectionVector(const Vec<T, Dim>& to) const -> Vec<T, Dim>
- Returns the direction vector from
this
toto
. - auto Absolute() const -> Vec<T, Dim>
- Returns a vector holding the absolute values of this vector.
- auto DistanceEuclidean(const Vec<T, Dim>& other) const -> double
- Computes the L2 distance between this and the other.
- auto DistanceManhattan(const Vec<T, Dim>& other) const -> double
- Computes the L1 distance between this and the other.
- auto Sum() const -> T
- Returns the sum over all dimensions.
- auto UnitVector() const -> Vec<double, Dim>
- Returns the unit vector.
-
auto MaxIndex() const -> index_
type - Returns the index/dimension holding the maximum value.
-
auto MinIndex() const -> index_
type - Returns the index/dimension holding the minimum value.
- auto MaxValue() const -> T
- Returns the maximum dimension value.
- auto MinValue() const -> T
- Returns the minimum dimension value.
- auto AngleRad(const Vec<T, Dim>& other) const -> double
- Returns the angle in [0, pi] between this and
other
. - auto AngleDeg(const Vec<T, Dim>& other) const -> double
- Returns the angle in [0, 180] between this and
other
. -
template<typename Tp = T>auto PerpendicularClockwise() const -> Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>
- Returns the 90° clock-wise rotated vector. This method assumes that the coordinate system is right-handed and is only supported for 2D vectors.
-
template<typename Tp = T>auto PerpendicularCounterClockwise() const -> Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>
- Returns the 90° counter-clock-wise rotated vector. This method assumes that the coordinate system is right-handed and is only supported for 2D vectors.
-
template<typename Tp = double>auto RotateRad(double angle_rad) const -> Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>
- Returns a copy of this vector rotated by the given radians.
-
template<typename Tp = double>auto RotateDeg(double angle_deg) const -> Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>
- Returns a double precision vector which is the result of rotating this vector by the given angle in degrees.
-
template<typename Tp = double>auto RotateRad(const Vec<Tp, 2>& rotation_center, double angle_rad) const -> Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>
-
template<typename Tp = double>auto RotateDeg(const Vec<Tp, 2>& rotation_center, double angle_deg) const -> Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim>
- auto ToString(bool include_type = true, int fixed_precision = 0) const -> std::string
- Returns a human-readable string representation. If
include_type
is true, the class name will be included, e.g. "Vec2i(1, 2)". Otherwise, it will only return the coordinates within parentheses, e.g. "(13, 77)".
Public variables
- T val
- Holds the values of this vector.
Friends
- auto operator==(const Vec<T, Dim>& lhs, const Vec<T, Dim>& rhs) -> bool
- Equality checks can be used for all vector specializations.
- auto operator!=(const Vec<T, Dim>& lhs, const Vec<T, Dim>& rhs) -> bool
- Inequality checks can be used for all vector specializations.
- auto operator+(Vec<T, Dim> lhs, const Vec<T, Dim>& rhs) -> Vec<T, Dim>
- Overloaded
vec1 + vec2
. By-value passing of lhs helps optimizing chained a+b+c equations. - auto operator+(Vec<T, Dim> lhs, T rhs) -> Vec<T, Dim>
- Overloaded
vec + scalar
. - auto operator+(T lhs, Vec<T, Dim> rhs) -> Vec<T, Dim>
- Overloaded
scalar + vec
. - auto operator-(Vec<T, Dim> lhs, const Vec<T, Dim>& rhs) -> Vec<T, Dim>
- Overloaded
vec1 -= vec2
. - auto operator-(Vec<T, Dim> lhs, T rhs) -> Vec<T, Dim>
- Overloaded
vec - scalar
. - auto operator-(T lhs, const Vec<T, Dim>& rhs) -> Vec<T, Dim>
- Overloaded
scalar - vec
, which isAll(scalar) - vec
. - auto operator*(Vec<T, Dim> lhs, T rhs) -> Vec<T, Dim>
- Overloaded
vec * scalar
. - auto operator*(T lhs, Vec<T, Dim> rhs) -> Vec<T, Dim>
- Overloaded
scalar * vec
. - auto operator*(Vec<T, Dim> lhs, const Vec<T, Dim>& rhs) -> Vec<T, Dim>
- Overloaded
vec1 * vec2
. -
template<typename Tp = T>auto operator/(Vec<T, Dim> lhs, double divisor) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>
- Overloaded for convenience. Divides each dimension by the given scalar. Only supported for floating point-based vector specializations.
-
template<typename Tp = T>auto operator/(Vec<T, Dim> lhs, const Vec<Tp, Dim>& divisor) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>
- Overloaded element-wise division, see
DivideVector
. Only supported for floating point-based vector specializations. -
template<typename Tp = T>auto operator/(Tp scalar, Vec<T, Dim> vec) -> Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>
- Returns a vector where each dimension is the result of the element-wise division `scalar / divisor[dimension]. Only supported for floating point-based vector specializations.
- auto operator<<(std::ostream& os, const Vec<T, Dim>& vec) -> std::ostream&
- Overloaded stream operator.
Function documentation
template<typename T, std::size_t Dim>
template<typename Tp = T>
bool werkzeugkiste:: geometry:: Vec<T, Dim>:: IsClose(const Vec<typename std::enable_if<std::is_floating_point<Tp>::value, Tp>::type, Dim>& other,
Tp relative_tolerance,
Tp absolute_tolerance) const
"Almost equal" check for vectors with floating point value type.
Returns true if all dimensions of both vectors are approximately equal, depending on both relative and absolute tolerance thresholds, see werkzeugkiste::
.
template<typename T, std::size_t Dim>
template<typename Tp = double>
Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim> werkzeugkiste:: geometry:: Vec<T, Dim>:: RotateRad(double angle_rad) const
Returns a copy of this vector rotated by the given radians.
This method assumes that the coordinate system is right-handed and is only supported for 2D vector specialization with floating point value type.
template<typename T, std::size_t Dim>
template<typename Tp = double>
Vec<typename std::enable_if<(Dim==2), Tp>::type, Dim> werkzeugkiste:: geometry:: Vec<T, Dim>:: RotateDeg(double angle_deg) const
Returns a double precision vector which is the result of rotating this vector by the given angle in degrees.
This method assumes that the coordinate system is right-handed and is only supported for 2D vectors.
template<typename T, std::size_t Dim>
std::string werkzeugkiste:: geometry:: Vec<T, Dim>:: ToString(bool include_type = true,
int fixed_precision = 0) const
Returns a human-readable string representation. If include_type
is true, the class name will be included, e.g. "Vec2i(1, 2)". Otherwise, it will only return the coordinates within parentheses, e.g. "(13, 77)".
For floating point types, the output precision will be set to the maximum precision if fixed_precision <= 0. If a positive fixed_precision is provided, the output format will be adjusted.
template<typename T, std::size_t Dim>
bool operator==(const Vec<T, Dim>& lhs,
const Vec<T, Dim>& rhs)
Equality checks can be used for all vector specializations.
Floating point value types use the IsClose
check with:
- relative tolerance of 1e-6 (float) and 1e-9 (double), and
- absolute tolerance of 1e-9 (float) and 1e-12 (double).
Float can store 6-9 significant digits, whereas double can typically store 15-18 significant digits. Given the usage scenarios of this template class, the above tolerances are sufficiently tight.