#include <vector.h>
template<typename T, std::size_t Dim>
werkzeugkiste::geometry::Vec class

Template class to represent a vector/coordinate.

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

static auto All(T value) -> Vec<T, Dim>
Returns a vector with all coordinates set to value.
static auto TypeName() -> std::string
Returns the class type name, e.g. "Vec2d".

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 or Dim 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, see AddVector.
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, see AddScalar.
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, see SubtractVector.
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, see SubtractScalar.
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, see MultiplyScalar.
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, see MultiplyVector.
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 to to.
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 is All(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::geometry::IsClose.

template<typename T, std::size_t Dim>
double werkzeugkiste::geometry::Vec<T, Dim>::AngleRad(const Vec<T, Dim>& other) const

Returns the angle in [0, pi] between this and other.

Returns The angle in radians.

template<typename T, std::size_t Dim>
double werkzeugkiste::geometry::Vec<T, Dim>::AngleDeg(const Vec<T, Dim>& other) const

Returns the angle in [0, 180] between this and other.

Returns The angle in degrees.

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.