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.
This commit is contained in:
2025-10-31 16:14:20 +03:00
parent ce9758c86b
commit 0510dd8328
5 changed files with 1015 additions and 1 deletions

View File

@@ -0,0 +1,297 @@
# `omath::Vector3` — 3D vector (C++20/23)
> Header: your projects `vector3.hpp`
> Namespace: `omath`
> Template: `template<class Type> requires std::is_arithmetic_v<Type>`
> Depends on: `omath::Vector2<Type>` (base class), `omath::Angle` (for `angle_between`)
> C++: uses `std::expected` ⇒ **C++23** recommended (or a backport)
`Vector3<Type>` extends `Vector2<Type>` with a `z` component and 3D operations: arithmetic, geometry (dot, cross, distance), normalization, angle-between with robust error signaling, hashing (for `float`) and `std::formatter` support.
---
## Quick start
```cpp
#include "vector3.hpp"
using omath::Vector3;
using Vec3f = Vector3<float>;
Vec3f a{3, 4, 0};
Vec3f b{1, 2, 2};
auto d = a.distance_to(b); // Euclidean distance
auto dot = a.dot(b); // 3*1 + 4*2 + 0*2 = 11
auto cr = a.cross(b); // (8, -6, 2)
auto len = a.length(); // hypot(x,y,z)
auto unit = a.normalized(); // safe normalize (returns a if length==0)
if (auto ang = a.angle_between(b)) {
float deg = ang->as_degrees(); // [0, 180], clamped
} else {
// vectors have zero length -> no defined angle
}
```
---
## Data members
```cpp
Type x{0}; // inherited from Vector2<Type>
Type y{0}; // inherited from Vector2<Type>
Type z{0};
```
---
## Constructors
```cpp
constexpr Vector3() noexcept;
constexpr Vector3(const Type& x, const Type& y, const Type& z) noexcept;
```
---
## Equality & ordering
```cpp
constexpr bool operator==(const Vector3&) const noexcept; // component-wise
constexpr bool operator!=(const Vector3&) const noexcept;
bool operator< (const Vector3&) const noexcept; // compare by length()
bool operator> (const Vector3&) const noexcept;
bool operator<=(const Vector3&) const noexcept;
bool operator>=(const Vector3&) const noexcept;
```
> **Note:** Ordering uses **magnitude**, not lexicographic order.
---
## Arithmetic (mutating)
Component-wise with another vector:
```cpp
Vector3& operator+=(const Vector3&) noexcept;
Vector3& operator-=(const Vector3&) noexcept;
Vector3& operator*=(const Vector3&) noexcept; // Hadamard product
Vector3& operator/=(const Vector3&) noexcept;
```
With a scalar:
```cpp
Vector3& operator*=(const Type& v) noexcept;
Vector3& operator/=(const Type& v) noexcept;
Vector3& operator+=(const Type& v) noexcept;
Vector3& operator-=(const Type& v) noexcept;
```
---
## Arithmetic (non-mutating)
```cpp
constexpr Vector3 operator-() const noexcept;
constexpr Vector3 operator+(const Vector3&) const noexcept;
constexpr Vector3 operator-(const Vector3&) const noexcept;
constexpr Vector3 operator*(const Vector3&) const noexcept; // Hadamard
constexpr Vector3 operator/(const Vector3&) const noexcept; // Hadamard
constexpr Vector3 operator*(const Type& scalar) const noexcept;
constexpr Vector3 operator/(const Type& scalar) const noexcept;
```
---
## Geometry & helpers
```cpp
// Distances & lengths
Type distance_to(const Vector3&) const; // sqrt of squared distance
constexpr Type distance_to_sqr(const Vector3&) const noexcept;
#ifndef _MSC_VER
constexpr Type length() const; // hypot(x,y,z)
constexpr Type length_2d() const; // 2D length from base
constexpr Vector3 normalized() const; // returns *this if length==0
#else
Type length() const noexcept;
Type length_2d() const noexcept;
Vector3 normalized() const noexcept;
#endif
constexpr Type length_sqr() const noexcept;
// Products
constexpr Type dot(const Vector3&) const noexcept;
constexpr Vector3 cross(const Vector3&) const noexcept; // right-handed
// Sums & tuples
constexpr Type sum() const noexcept; // x + y + z
constexpr Type sum_2d() const noexcept; // x + y
constexpr auto as_tuple() const noexcept -> std::tuple<Type,Type,Type>;
// Utilities
Vector3& abs() noexcept; // component-wise absolute
```
---
## Angles & orthogonality
```cpp
enum class Vector3Error { IMPOSSIBLE_BETWEEN_ANGLE };
// Angle in degrees, clamped to [0,180]. Error if any vector has zero length.
std::expected<
omath::Angle<float, 0.f, 180.f, AngleFlags::Clamped>,
Vector3Error
> angle_between(const Vector3& other) const noexcept;
bool is_perpendicular(const Vector3& other) const noexcept; // true if angle == 90°
```
---
## Hashing & formatting
* **Hash (for `Vector3<float>`)**
```cpp
template<> struct std::hash<omath::Vector3<float>> {
std::size_t operator()(const omath::Vector3<float>&) const noexcept;
};
```
Example:
```cpp
std::unordered_map<omath::Vector3<float>, int> counts;
counts[{1.f, 2.f, 3.f}] = 7;
```
* **`std::formatter`** (all character types)
```cpp
template<class Type>
struct std::formatter<omath::Vector3<Type>>; // prints "[x, y, z]"
```
---
## Error handling
* `angle_between()` returns `std::unexpected(Vector3Error::IMPOSSIBLE_BETWEEN_ANGLE)` if either vector length is zero.
* Other operations are total for arithmetic `Type` (no throwing behavior in this class).
---
## Examples
### Cross product & perpendicular check
```cpp
omath::Vector3<float> x{1,0,0}, y{0,1,0};
auto z = x.cross(y); // (0,0,1)
bool perp = x.is_perpendicular(y); // true
```
### Safe normalization and angle
```cpp
omath::Vector3<float> u{0,0,0}, v{1,1,0};
auto nu = u.normalized(); // returns {0,0,0}
if (auto ang = u.angle_between(v)) {
// won't happen: u has zero length → error
} else {
// handle degenerate case
}
```
### Hadamard vs scalar multiply
```cpp
omath::Vector3<float> a{2,3,4}, b{5,6,7};
auto h = a * b; // (10, 18, 28) component-wise
auto s = a * 2.f; // (4, 6, 8) scalar
```
---
## API summary (signatures)
```cpp
// Ctors
constexpr Vector3() noexcept;
constexpr Vector3(const Type& x, const Type& y, const Type& z) noexcept;
// Equality & ordering
constexpr bool operator==(const Vector3&) const noexcept;
constexpr bool operator!=(const Vector3&) const noexcept;
bool operator< (const Vector3&) const noexcept;
bool operator> (const Vector3&) const noexcept;
bool operator<=(const Vector3&) const noexcept;
bool operator>=(const Vector3&) const noexcept;
// Mutating arithmetic
Vector3& operator+=(const Vector3&) noexcept;
Vector3& operator-=(const Vector3&) noexcept;
Vector3& operator*=(const Vector3&) noexcept;
Vector3& operator/=(const Vector3&) noexcept;
Vector3& operator*=(const Type&) noexcept;
Vector3& operator/=(const Type&) noexcept;
Vector3& operator+=(const Type&) noexcept;
Vector3& operator-=(const Type&) noexcept;
// Non-mutating arithmetic
constexpr Vector3 operator-() const noexcept;
constexpr Vector3 operator+(const Vector3&) const noexcept;
constexpr Vector3 operator-(const Vector3&) const noexcept;
constexpr Vector3 operator*(const Vector3&) const noexcept;
constexpr Vector3 operator/(const Vector3&) const noexcept;
constexpr Vector3 operator*(const Type&) const noexcept;
constexpr Vector3 operator/(const Type&) const noexcept;
// Geometry
Type distance_to(const Vector3&) const;
constexpr Type distance_to_sqr(const Vector3&) const noexcept;
#ifndef _MSC_VER
constexpr Type length() const;
constexpr Type length_2d() const;
constexpr Vector3 normalized() const;
#else
Type length() const noexcept;
Type length_2d() const noexcept;
Vector3 normalized() const noexcept;
#endif
constexpr Type length_sqr() const noexcept;
constexpr Type dot(const Vector3&) const noexcept;
constexpr Vector3 cross(const Vector3&) const noexcept;
Vector3& abs() noexcept;
constexpr Type sum() const noexcept;
constexpr Type sum_2d() const noexcept;
constexpr auto as_tuple() const noexcept -> std::tuple<Type,Type,Type>;
// Angles
std::expected<omath::Angle<float,0.f,180.f,AngleFlags::Clamped>, omath::Vector3Error>
angle_between(const Vector3&) const noexcept;
bool is_perpendicular(const Vector3&) const noexcept;
// Hash (float) and formatter specializations provided below the class
```
---
## Notes
* Inherits all public API of `Vector2<Type>` (including `x`, `y`, many operators, and helpers used internally).
* `normalized()` returns the original vector if its length is zero (no NaNs).
* `cross()` uses the standard right-handed definition.
* `length()`/`normalized()` are `constexpr` on non-MSVC; MSVC builds provide `noexcept` runtime versions.
---
*Last updated: 31 Oct 2025*