summary refs log tree commit diff
path: root/src/Math/Vector.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Math/Vector.hpp')
-rw-r--r--src/Math/Vector.hpp79
1 files changed, 60 insertions, 19 deletions
diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp
index 260891d..54207f0 100644
--- a/src/Math/Vector.hpp
+++ b/src/Math/Vector.hpp
@@ -10,31 +10,36 @@ struct Vector {
     Vector(): elements{} {};
 
     template<typename ...Args, std::enable_if_t<sizeof...(Args) == S, int> = 0>
-    Vector<S, T>(Args... args) : elements{ args... } {};
+    Vector(Args... args) : elements{ args... } {};
 
-    Vector<S, T>(T values[S]) {
+    Vector(const T values[S]) {
         std::copy(values, values + S, elements);
     };
 
-    Vector<S, T>(T scalar) {
+    explicit Vector(const T scalar) {
         std::fill(elements, elements + S, scalar);
     };
 
-    Vector<S, T>(Vector<S - 1, T> vector, T scalar) {
+    Vector(const Vector<S - 1, T> vector, const T scalar) {
         std::copy(vector.elements, vector.elements + S - 1, elements);
         elements[S - 1] = scalar;
     }
 
-    Vector<S, T> map(std::function<T(T)> f) const {
-        Vector<S, T> result{};
+    template<size_t N, std::enable_if_t<(N > S), int> = 0>
+    explicit Vector(const Vector<N, T> vector) {
+        std::copy(vector.elements, vector.elements + S, elements);
+    }
+
+    Vector map(std::function<T(T)> f) const {
+        Vector result{};
         for (int i = 0; i < S; i++) {
             result[i] = f(elements[i]);
         }
         return result;
     }
 
-    Vector<S, T> map(std::function<T(size_t, T)> f) const {
-        Vector<S, T> result{};
+    Vector map(std::function<T(size_t, T)> f) const {
+        Vector result{};
         for (int i = 0; i < S; i++) {
             result[i] = f(i, elements[i]);
         }
@@ -57,20 +62,27 @@ struct Vector {
         return sqrt(map([](auto x) { return x * x;}).sum());
     }
 
-    Vector<S, T> normalize() const {
+    Vector normalize() const {
         auto m = magnitude();
         return map([=](auto x) { return x / m; });
     }
 
-    T distance(Vector<S, T> other) const {
+    T distance(const Vector other) const {
         return (*this - other).magnitude();
     }
 
-    Vector<S, T> abs() const {
+    Vector<3, T> any_orthogonal() {
+        if (Vector a{y(), -x(), 0.0f}; a != zero()) return a;
+        if (Vector b{z(), 0.0f, -x()}; b != zero()) return b;
+        if (Vector c{0.0f, z(), -y()}; c != zero()) return c;
+        return zero();
+    }
+
+    Vector abs() const {
         return map([=](auto x) { return std::abs(x); });
     }
 
-    Vector<3, T> cross(Vector<3, T> other) const {
+    Vector<3, T> cross(const Vector<3, T> other) const {
         return {
             y() * other.z() - z() * other.y(),
             z() * other.x() - x() * other.z(),
@@ -86,34 +98,52 @@ struct Vector {
         return elements[index];
     }
 
-    Vector<S, T> operator+(Vector<S, T> other) const {
+    Vector operator+(const Vector other) const {
         return map([&](auto i, auto x) { return x + other[i]; });
     }
 
-    Vector<S, T> operator+(T scalar) const {
+    Vector operator+(T scalar) const {
         return map([=](auto x) { return x + scalar; });
     }
 
-    Vector<S, T> operator*(T scalar) const {
+    Vector operator*(T scalar) const {
         return map([=](auto x) { return x * scalar; });
     }
 
-    T operator*(Vector<S, T> other) const {
+    T operator*(const Vector other) const {
         return map([&](auto i, auto x) { return x * other[i]; }).sum();
     }
 
-    Vector<S, T> operator-(Vector<S, T> other) const {
+    Vector operator-(const Vector other) const {
         return map([&](auto i, auto x) { return x - other[i]; });
     }
 
-    Vector<S, T> operator-() const {
+    Vector operator-() const {
         return map([](T x) -> T { return -x; });
     }
 
-    Vector<S, T> operator/(T scalar) const {
+    Vector operator/(T scalar) const {
         return map([=](auto x) { return x / scalar; });
     }
 
+    bool operator==(const Vector& other) {
+        for (int i = 0; i < S; i++) {
+            if (elements[i] != other[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool operator!=(const Vector& other) {
+        return !this->operator==(other);
+    }
+
+    Vector& operator+=(const Vector& other) {
+        *this = *this + other;
+        return *this;
+    }
+
     T& x() { static_assert(S > 0); return elements[0]; }
     const T& x() const { static_assert(S > 0); return elements[0]; }
 
@@ -138,5 +168,16 @@ struct Vector {
         return str.str();
     }
 
+    static Vector<3, T> up() { return {(T)0, (T)1, (T)0}; }
+    static Vector<3, T> down() { return {(T)0, (T)-1, (T)0}; }
+    static Vector<3, T> forward() { return {(T)0, (T)0, (T)1}; }
+    static Vector<3, T> back() { return {(T)0, (T)0, (T)-1}; }
+    static Vector<3, T> right() { return {(T)1, (T)0, (T)0}; }
+    static Vector<3, T> left() { return {(T)-1, (T)0, (T)0}; }
+
+    static Vector<3, T> one() { return Vector{(T)1}; }
+    static Vector<3, T> zero() { return Vector{(T)0}; }
+    static Vector<3, T> max() { return Vector{(T)std::numeric_limits<T>::max()}; }
+
     T elements[S];
 };