#pragma once #include "FrameworkMath.h" namespace Framework { template< typename T, int N> //! Ein 3D Vektor class VecN { private: T v[N]; public: //! Konstruktor inline VecN() {} //! Konstruktor //! \param v die werte des Vectors inline VecN(const T v[N]) { memcpy(this->v, v, sizeof(T) * N); } inline VecN(std::initializer_list l) { assert(l.size() == N); int i = 0; for (auto v : l) { this->v[i] = v; i++; } } //! Konstruktor //! \param vect Ein Vektor, dessen Werte kopiert werden sollen inline VecN(const VecN& vect) : VecN(vect.v) {} //! Skalliert den Vektor, so dass er die Länge 1 hat inline VecN& normalize() { const T length = getLength(); for (i = 0; i < N; i++) v[i] /= length; return *this; } //! Vertaucht die Werte des Vektors mit denen eines anderen Vektor //! \param vect Der andere Vektor inline VecN& swap(VecN& vect) { const VecN tmp = vect; vect = *this; *this = tmp; return *this; } //! Berechnet einen winkel zwischen diesem und einem anderen Vektor inline float angle(VecN vect) { return lowPrecisionACos((float)(*this * vect) / ((float)getLength() * (float)vect.getLength())); } //! Kopiert die Werte eines anderen Vektors //! \param r Der andere Vektor inline VecN operator=(const VecN& r) { memcpy(v, r.v, sizeof(T) * N); return *this; } //! Addiert einen anderen Vektor zu diesem Hinzu //! \param r Der andere Vektor inline VecN operator+=(const VecN& r) { for (int i = 0; i < N; i++) v[i] += r.v[i]; return *this; } //! Zieht einen anderen Vektor von diesem ab //! \param r Der andere Vektor inline VecN operator-=(const VecN& r) { for (int i = 0; i < N; i++) v[i] -= r.v[i]; return *this; } //! Skalliert diesen Vektor //! \param r Der Faktor inline VecN operator*=(const T& r) { for (int i = 0; i < N; i++) v[i] *= r; return *this; } //! Skalliert diesen Vektor mit 1/Faktor //! \param r Der Faktor inline VecN operator/=(const T& r) { for (int i = 0; i < N; i++) v[i] /= r; return *this; } //! Errechnet das Quadrat des Abstands zwischen zewi Vektoren //! \param p Der andere Vektor inline T abstandSq(const VecN& p) const { T sum = (T)0; for (int i = 0; i < N; i++) sum += (v[i] - p.v[i]) * (v[i] - p.v[i]); return sum; } //! Errechnet den Abstand zwischen zwei Vektoren //! \param p Der andere Vektor inline T abstand(const VecN& p) const { return sqrt(abstandSq(p)); } //! Gibt einen neuen Vektor zurück, der die negation von diesem ist inline VecN operator-() const { T r[N]; for (int i = 0; i < N; i++) r[i] = -v[i]; return { r }; } template< typename T2 > //! Konvertiert den Typ des Vektors in einen anderen inline operator VecN< T2, N >() const { T2 r[N]; for (int i = 0; i < N; i++) r[i] = (T2)v[i]; return { r }; } //! Errechnet das Quadrat der Länge des Vektors inline T getLengthSq() const { return *this * *this; } //! Errechnet due Länge des Vektors inline T getLength() const { return (T)sqrt(getLengthSq()); } //! Bildet das Skalarprodukt zwischen zwei Vektoren //! \param r Der andere Vektor inline T operator*(const VecN& r) const { T sum = (T)0; for (int i = 0; i < N; i++) sum += v[i] * r.v[i]; return sum; } //! Errechnet die Summe zweier Vektoren //! \param r Der andere Vektor inline VecN operator+(const VecN& r) const { return VecN(*this) += r; } //! Zieht zwei Vektoren von einander ab //! \param r Der andere Vektor inline VecN operator-(const VecN& r) const { return VecN(*this) -= r; } //! Skalliert den Vektor ohne ihn zu verändern //! \param r Der Faktor inline VecN operator*(const T& r) const { return VecN(*this) *= r; } //! Skalliert den Vektor mit 1/Faktor ohne ihn zu Verändern //! \param r Der Faktor inline VecN operator/(const T& r) const { return VecN(*this) /= r; } //! Überprüft zwei Vektoren auf Gleichheit //! \param r Der andere Vektor inline bool operator==(const VecN& r) const { for (int i = 0; i < N; i++) { if (v[i] != r.v[i]) return 0; } return 1; } //! Überprüft zwei Vektoren auf Ungleichheit //! \param r Der andere Vektor inline bool operator!=(const VecN& r) const { return !(*this == r); } inline T operator[](int i) const { return v[i]; } }; }