omath::Vector2 — 2D vector (C++20/23)
Header: your project’s
vector2.hppNamespace:omathTemplate:template<class Type> requires std::is_arithmetic_v<Type>
Vector2<Type> is a lightweight, POD-like 2D math type with arithmetic, geometry helpers, comparisons, hashing (for float), optional ImGui interop, and std::formatter support.
Quick start
#include "vector2.hpp"
using omath::Vector2;
using Vec2f = Vector2<float>;
Vec2f a{3.f, 4.f};
Vec2f b{1.f, 2.f};
auto d = a.distance_to(b); // ≈ 3.1623
auto dot = a.dot(b); // 11
auto len = a.length(); // 5
auto unit_a = a.normalized(); // (0.6, 0.8)
// Component-wise mutate
Vec2f c{2, 3};
c *= b; // c -> (2*1, 3*2) = (2, 6)
// Scalar ops (non-mutating + mutating)
auto scaled = a * 0.5f; // (1.5, 2)
a *= 2.f; // (6, 8)
// Ordering by length()
bool shorter = (b < a);
// Formatted printing
std::string s = std::format("a = {}", a); // "a = [6, 8]"
Members
Type x{0};
Type y{0};
Constructors
constexpr Vector2(); // (0,0)
constexpr Vector2(const Type& x, const Type& y) noexcept;
Equality & ordering
constexpr bool operator==(const Vector2&) const noexcept; // component-wise equality
constexpr bool operator!=(const Vector2&) const noexcept;
bool operator< (const Vector2&) const noexcept; // compares by length()
bool operator> (const Vector2&) const noexcept;
bool operator<=(const Vector2&) const noexcept;
bool operator>=(const Vector2&) const noexcept;
Note:
<,>,<=,>=order vectors by magnitude (not lexicographically).
Arithmetic
With another vector (component-wise, mutating)
Vector2& operator+=(const Vector2&) noexcept;
Vector2& operator-=(const Vector2&) noexcept;
Vector2& operator*=(const Vector2&) noexcept; // Hadamard product (x*=x, y*=y)
Vector2& operator/=(const Vector2&) noexcept;
Non-mutating
v * u/v / u(vector × vector) are not provided. Usev *= u(mutating) or build a new vector explicitly.
With a scalar
Vector2& operator*=(const Type& v) noexcept;
Vector2& operator/=(const Type& v) noexcept;
Vector2& operator+=(const Type& v) noexcept;
Vector2& operator-=(const Type& v) noexcept;
constexpr Vector2 operator*(const Type& v) const noexcept;
constexpr Vector2 operator/(const Type& v) const noexcept;
Binary (+/−) with another vector (non-mutating)
constexpr Vector2 operator+(const Vector2&) const noexcept;
constexpr Vector2 operator-(const Vector2&) const noexcept;
Unary
constexpr Vector2 operator-() const noexcept; // negation
Geometry & helpers
Type distance_to (const Vector2&) const noexcept; // sqrt of squared distance
constexpr Type distance_to_sqr(const Vector2&) const noexcept;
constexpr Type dot(const Vector2&) const noexcept;
#ifndef _MSC_VER
constexpr Type length() const noexcept; // uses std::hypot; constexpr on non-MSVC
constexpr Vector2 normalized() const noexcept; // returns *this if length==0
#else
Type length() const noexcept;
Vector2 normalized() const noexcept;
#endif
constexpr Type length_sqr() const noexcept; // x*x + y*y
Vector2& abs() noexcept; // component-wise absolute (constexpr-friendly impl)
constexpr Type sum() const noexcept; // x + y
constexpr std::tuple<Type, Type> as_tuple() const noexcept;
ImGui integration (optional)
Define OMATH_IMGUI_INTEGRATION before including the header.
#ifdef OMATH_IMGUI_INTEGRATION
constexpr ImVec2 to_im_vec2() const noexcept; // {float(x), float(y)}
static Vector2 from_im_vec2(const ImVec2&) noexcept;
#endif
Hashing & formatting
- Hash (for
Vector2<float>)
cpp
template<> struct std::hash<omath::Vector2<float>> {
std::size_t operator()(const omath::Vector2<float>&) const noexcept;
};
Example:
cpp
std::unordered_set<omath::Vector2<float>> set;
set.insert({1.f, 2.f});
std::formatter(for anyType)
cpp
// prints "[x, y]" for char / wchar_t / char8_t
template<class Type>
struct std::formatter<omath::Vector2<Type>>;
Notes & invariants
Typemust be arithmetic (e.g.,float,double,int, …).normalized()returns the input unchanged iflength() == 0.abs()uses a constexpr-friendly implementation (notstd::abs) to allow compile-time evaluation.- On MSVC,
length()/normalized()are notconstexprdue to library constraints; they’re stillnoexcept.
Examples
Component-wise operations and scalar scaling
omath::Vector2<float> u{2, 3}, v{4, 5};
u += v; // (6, 8)
u -= v; // (2, 3)
u *= v; // (8, 15) Hadamard product (mutates u)
auto w = v * 2.0f; // (8, 10) non-mutating scalar multiply
Geometry helpers
omath::Vector2<double> p{0.0, 0.0}, q{3.0, 4.0};
auto dsq = p.distance_to_sqr(q); // 25
auto d = p.distance_to(q); // 5
auto dot = p.dot(q); // 0
auto uq = q.normalized(); // (0.6, 0.8)
Using as a key in unordered containers (float)
std::unordered_map<omath::Vector2<float>, int> counts;
counts[{1.f, 2.f}] = 42;
ImGui interop
#define OMATH_IMGUI_INTEGRATION
#include "vector2.hpp"
omath::Vector2<float> v{10, 20};
ImVec2 iv = v.to_im_vec2();
v = omath::Vector2<float>::from_im_vec2(iv);
API summary (signatures)
// Constructors
constexpr Vector2();
constexpr Vector2(const Type& x, const Type& y) noexcept;
// Equality & ordering
constexpr bool operator==(const Vector2&) const noexcept;
constexpr bool operator!=(const Vector2&) const noexcept;
bool operator< (const Vector2&) const noexcept;
bool operator> (const Vector2&) const noexcept;
bool operator<=(const Vector2&) const noexcept;
bool operator>=(const Vector2&) const noexcept;
// Compound (vector/vector and scalar)
Vector2& operator+=(const Vector2&) noexcept;
Vector2& operator-=(const Vector2&) noexcept;
Vector2& operator*=(const Vector2&) noexcept;
Vector2& operator/=(const Vector2&) noexcept;
Vector2& operator*=(const Type&) noexcept;
Vector2& operator/=(const Type&) noexcept;
Vector2& operator+=(const Type&) noexcept;
Vector2& operator-=(const Type&) noexcept;
// Non-mutating arithmetic
constexpr Vector2 operator+(const Vector2&) const noexcept;
constexpr Vector2 operator-(const Vector2&) const noexcept;
constexpr Vector2 operator*(const Type&) const noexcept;
constexpr Vector2 operator/(const Type&) const noexcept;
constexpr Vector2 operator-() const noexcept;
// Geometry
Type distance_to(const Vector2&) const noexcept;
constexpr Type distance_to_sqr(const Vector2&) const noexcept;
constexpr Type dot(const Vector2&) const noexcept;
Type length() const noexcept; // constexpr on non-MSVC
Vector2 normalized() const noexcept; // constexpr on non-MSVC
constexpr Type length_sqr() const noexcept;
Vector2& abs() noexcept;
constexpr Type sum() const noexcept;
constexpr std::tuple<Type,Type> as_tuple() const noexcept;
// ImGui (optional)
#ifdef OMATH_IMGUI_INTEGRATION
constexpr ImVec2 to_im_vec2() const noexcept;
static Vector2 from_im_vec2(const ImVec2&) noexcept;
#endif
// Hash (float) and formatter are specialized in the header
See Also
- Vector3 Documentation - 3D vector operations
- Vector4 Documentation - 4D vector operations
- Getting Started Guide - Quick start with OMath
- Tutorials - Step-by-step examples
Last updated: 1 Nov 2025