Files
omath/docs/linear_algebra/vector4.md
Orange 0510dd8328 Adds documentation for Vector4 and incorporates ImGui integration
Adds comprehensive documentation for the `Vector4` class, outlining constructors, operators, and utility functions. Includes detailed notes on `clamp` functionality and potential ImGui integration caveats. Incorporates optional ImGui integration with explanations for correct usage and potential improvements.
2025-10-31 16:14:20 +03:00

254 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `omath::Vector4` — 4D vector (C++20/23)
> Header: your projects `vector4.hpp`
> Namespace: `omath`
> Template: `template<class Type> requires std::is_arithmetic_v<Type>`
> Inherits: `omath::Vector3<Type>` (brings `x`, `y`, `z` and most scalar ops)
`Vector4<Type>` extends `Vector3<Type>` with a `w` component and 4D operations: component-wise arithmetic, scalar ops, dot/length helpers, clamping, hashing (for `float`) and `std::formatter` support. Optional ImGui interop is available behind a macro.
---
## Quick start
```cpp
#include "vector4.hpp"
using omath::Vector4;
using Vec4f = Vector4<float>;
Vec4f a{1, 2, 3, 1};
Vec4f b{4, 5, 6, 2};
// Component-wise & scalar ops
auto c = a + b; // (5, 7, 9, 3)
c *= 0.5f; // (2.5, 3.5, 4.5, 1.5)
auto h = a * b; // Hadamard: (4, 10, 18, 2)
// Dot / length
float d = a.dot(b); // 1*4 + 2*5 + 3*6 + 1*2 = 32
float L = a.length(); // sqrt(x²+y²+z²+w²)
// Clamp (x,y,z only; see notes)
Vec4f col{1.4f, -0.2f, 0.7f, 42.f};
col.clamp(0.f, 1.f); // -> (1, 0, 0.7, w unchanged)
```
---
## Data members
```cpp
// Inherited from Vector3<Type>:
Type x{0};
Type y{0};
Type z{0};
// Added in Vector4:
Type w{0};
```
---
## Constructors
```cpp
constexpr Vector4() noexcept; // (0,0,0,0)
constexpr Vector4(const Type& x, const Type& y,
const Type& z, const Type& w); // value-init
```
---
## Equality & ordering
```cpp
constexpr bool operator==(const Vector4&) const noexcept; // component-wise
constexpr bool operator!=(const Vector4&) const noexcept;
bool operator< (const Vector4&) const noexcept; // compare by length()
bool operator> (const Vector4&) const noexcept;
bool operator<=(const Vector4&) const noexcept;
bool operator>=(const Vector4&) const noexcept;
```
> **Note:** Ordering uses **magnitude** (Euclidean norm), not lexicographic order.
---
## Arithmetic (mutating)
With another vector (component-wise):
```cpp
Vector4& operator+=(const Vector4&) noexcept;
Vector4& operator-=(const Vector4&) noexcept;
Vector4& operator*=(const Vector4&) noexcept; // Hadamard
Vector4& operator/=(const Vector4&) noexcept;
```
With a scalar:
```cpp
Vector4& operator*=(const Type& v) noexcept;
Vector4& operator/=(const Type& v) noexcept;
// From base class (inherited):
Vector4& operator+=(const Type& v) noexcept; // adds v to x,y,z (and w via base? see notes)
Vector4& operator-=(const Type& v) noexcept;
```
---
## Arithmetic (non-mutating)
```cpp
constexpr Vector4 operator-() const noexcept;
constexpr Vector4 operator+(const Vector4&) const noexcept;
constexpr Vector4 operator-(const Vector4&) const noexcept;
constexpr Vector4 operator*(const Vector4&) const noexcept; // Hadamard
constexpr Vector4 operator/(const Vector4&) const noexcept; // Hadamard
constexpr Vector4 operator*(const Type& scalar) const noexcept;
constexpr Vector4 operator/(const Type& scalar) const noexcept;
```
---
## Geometry & helpers
```cpp
constexpr Type length_sqr() const noexcept; // x² + y² + z² + w²
Type length() const noexcept; // std::sqrt(length_sqr())
constexpr Type dot(const Vector4& rhs) const noexcept;
Vector4& abs() noexcept; // component-wise absolute
Vector4& clamp(const Type& min, const Type& max) noexcept;
// clamps x,y,z; leaves w unchanged (see notes)
constexpr Type sum() const noexcept; // x + y + z + w
```
---
## ImGui integration (optional)
Guarded by `OMATH_IMGUI_INTEGRATION`:
```cpp
#ifdef OMATH_IMGUI_INTEGRATION
constexpr ImVec4 to_im_vec4() const noexcept;
// NOTE: Provided signature returns Vector4<float> and (in current code) sets only x,y,z.
// See "Notes & caveats" for a corrected version you may prefer.
static Vector4<float> from_im_vec4(const ImVec4& other) noexcept;
#endif
```
---
## Hashing & formatting
* **Hash specialization** (only for `Vector4<float>`):
```cpp
template<> struct std::hash<omath::Vector4<float>> {
std::size_t operator()(const omath::Vector4<float>&) const noexcept;
};
```
Example:
```cpp
std::unordered_map<omath::Vector4<float>, int> counts;
counts[{1.f, 2.f, 3.f, 1.f}] = 7;
```
* **`std::formatter`** (for any `Type`, all character kinds):
```cpp
template<class Type>
struct std::formatter<omath::Vector4<Type>>; // -> "[x, y, z, w]"
```
---
## Notes & caveats (as implemented)
* `clamp(min,max)` **clamps only `x`, `y`, `z`** and **does not clamp `w`**. This may be intentional (e.g., when `w` is a homogeneous coordinate) — document your intent in your codebase.
If you want to clamp `w` too:
```cpp
w = std::clamp(w, min, max);
```
* **ImGui interop**:
* The header references `ImVec4` but does not include `<imgui.h>` itself. Ensure its included **before** this header whenever `OMATH_IMGUI_INTEGRATION` is defined.
* `from_im_vec4` currently returns `Vector4<float>` and (in the snippet shown) initializes **only x,y,z**. A more consistent version would be:
```cpp
#ifdef OMATH_IMGUI_INTEGRATION
static Vector4<Type> from_im_vec4(const ImVec4& v) noexcept {
return {static_cast<Type>(v.x), static_cast<Type>(v.y),
static_cast<Type>(v.z), static_cast<Type>(v.w)};
}
#endif
```
* Many scalar compound operators (`+= Type`, `-= Type`) are inherited from `Vector3<Type>`.
---
## API summary (signatures)
```cpp
// Ctors
constexpr Vector4() noexcept;
constexpr Vector4(const Type& x, const Type& y, const Type& z, const Type& w);
// Equality & ordering
constexpr bool operator==(const Vector4&) const noexcept;
constexpr bool operator!=(const Vector4&) const noexcept;
bool operator< (const Vector4&) const noexcept;
bool operator> (const Vector4&) const noexcept;
bool operator<=(const Vector4&) const noexcept;
bool operator>=(const Vector4&) const noexcept;
// Mutating arithmetic
Vector4& operator+=(const Vector4&) noexcept;
Vector4& operator-=(const Vector4&) noexcept;
Vector4& operator*=(const Vector4&) noexcept;
Vector4& operator/=(const Vector4&) noexcept;
Vector4& operator*=(const Type&) noexcept;
Vector4& operator/=(const Type&) noexcept;
// (inherited) Vector4& operator+=(const Type&) noexcept;
// (inherited) Vector4& operator-=(const Type&) noexcept;
// Non-mutating arithmetic
constexpr Vector4 operator-() const noexcept;
constexpr Vector4 operator+(const Vector4&) const noexcept;
constexpr Vector4 operator-(const Vector4&) const noexcept;
constexpr Vector4 operator*(const Vector4&) const noexcept;
constexpr Vector4 operator/(const Vector4&) const noexcept;
constexpr Vector4 operator*(const Type&) const noexcept;
constexpr Vector4 operator/(const Type&) const noexcept;
// Geometry & helpers
constexpr Type length_sqr() const noexcept;
Type length() const noexcept;
constexpr Type dot(const Vector4&) const noexcept;
Vector4& abs() noexcept;
Vector4& clamp(const Type& min, const Type& max) noexcept;
constexpr Type sum() const noexcept;
// ImGui (optional)
#ifdef OMATH_IMGUI_INTEGRATION
constexpr ImVec4 to_im_vec4() const noexcept;
static Vector4<float> from_im_vec4(const ImVec4&) noexcept; // see note for preferred template version
#endif
// Hash (float) and formatter specializations provided below the class
```
---
*Last updated: 31 Oct 2025*