#ifndef Vec2_H #define Vec2_H #include "FrameworkMath.h" namespace Framework { //! Ein zweidimensionaler Vektor template< typename T > class Vec2 { public: T x; //! x Komponente des Vektors T y; //! y Komponente des Vektors //! Konstruktor inline Vec2() noexcept : x( 0 ), y( 0 ) {} //! Konstruktor //! \param x X Komponente des Vektors //! \param y Y Komponente des Vektors inline Vec2( T x, T y ) : x( x ), y( y ) {} //! Konstruktor //! \param vect Ein Vektor, dessen Komponenten übernommen werden inline Vec2( const Vec2 &vect ) : x( (T)vect.x ), y( (T)vect.y ) {} //! Skalliert den Vektor, so dass er die Länge 1 hat inline Vec2 &normalize() { const T length = getLength(); x /= length; y /= length; return *this; } //! Dreht den Vektor um 90 Grad gegen den Uhrzeigersinn inline Vec2 &CCW90() { T temp = y; y = -x; x = temp; return *this; } //! Dreht den Vektor um 90 Grad im Uhrzeigersinn inline Vec2 &CW90() { T temp = y; y = x; x = -temp; return *this; } //! Tauscht die Werte der Vektoren aus //! \param vect Der Vektor, mit dem getauscht werden soll inline Vec2 &Swap( Vec2 &vect ) { const Vec2 tmp = vect; vect = *this; *this = tmp; return *this; } //! nimmt die Werte eines anderen Vektors an //! \param r Der andere Vektor inline Vec2 operator=( const Vec2 &r ) { x = r.x; y = r.y; return *this; } //! addiert einen anderen Vektor zu diesem hinzu //! \param r Der andere Vektor inline Vec2 operator+=( const Vec2 &r ) { x += r.x; y += r.y; return *this; } //! Zieht einen anderen Vektor von diesem ab //! \param r Der andere Vektor inline Vec2 operator-=( const Vec2 &r ) { x -= r.x; y -= r.y; return *this; } //! Skalliert diesen Vektor mit einem anderen Vektor //! \param r Der andere Vektor inline Vec2 operator*=( const T &r ) { x *= r; y *= r; return *this; } //! Verkürtzt diesen Vektor durch einen anderen Vektor //! \param r Der andere Vektor inline Vec2 operator/=( const T &r ) { x /= r; y /= r; return *this; } //! Bildet die Negation des Vektors inline Vec2 operator-() const { return Vec2< T >( -x, -y ); } //! Konvertiert den Vektor in ein Vektor eines anderen Typs template< typename T2 > inline operator Vec2< T2 >() const { return Vec2< T2 >( (T2)x, (T2)y ); } //! Errechnet das Quadrat der Länge desVektors inline T getLengthSq() const { return *this * *this; } //! Errechnet die Länge des Vektors inline T getLength() const { return (T)sqrt( getLengthSq() ); } //! Errechnet das Skalarprodukt zwischen zwei Vektoren //! \param r Der andere Vektor inline T operator*( const Vec2 &r ) const { return x * r.x + y * r.y; } //! Addiert zwei Vektoren //! \param r Der andere Vektor inline Vec2 operator+( const Vec2 &r ) const { return Vec2( *this ) += r; } //! Subtrahiert zwei Vektoren //! \param r Der andere Vektor inline Vec2 operator-( const Vec2 &r ) const { return Vec2( *this ) -= r; } //! Multipliziert die Komponenten zweier Vektoren //! \param r Der andere Vektor inline Vec2 operator*( const T &r ) const { return Vec2( *this ) *= r; } //! Dividiert die Komponenten zweier Vektoren //! \param r Der andere Vektor inline Vec2 operator/( const T &r ) const { return Vec2( *this ) /= r; } //! Prüft, ob sich der Vektor in dem Rechteck zwischen zwei Vektoren befindet //! p1: Ein Vektor zur einen Ecke des Rechtecks //! p2: Ein Vektor zur gegenüberliegenden Ecke des Rechtecks inline bool istInRegion( const Vec2 &p1, const Vec2 &p2 ) const { const T medianX = (T)( ( p1.x + p2.x ) / 2.0 ); const T medianY = (T)( ( p1.y + p2.y ) / 2.0 ); return abs< T >( medianX - x ) <= abs< T >( medianX - p1.x ) && abs< T >( medianY - y ) <= abs< T >( medianY - p1.y ); } //! Überprüft zwei Vektoren auf Gleichheit //! \param r Der andere Vektor inline bool operator==( const Vec2 &r ) const { return x == r.x && y == r.y; } //! Überprüft zwei Vektoren auf Ungleichheit //! \param r Der andere Vektor inline bool operator!=( const Vec2 &r ) const { return !( *this == r ); } //! Errechnet den Mittelpunkt zwischen zwei Vektoren //! p2: Der andere Vektor inline Vec2 mittelpunktMit( const Vec2 &p2 ) const { return Vec2( (T)( ( x + p2.x ) / 2.0 ), (T)( ( y + p2.y ) / 2.0 ) ); } //! Rotiert den Vektor gegen den Uhrzeigersinn //! \param angle Der Winkel in Bogenmas inline Vec2 rotation( const float angle ) const { Vec2 result; float cosine = lowPrecisionCos( angle ); float sine = lowPrecisionSin( angle ); result.x = (T)( x * cosine - y * sine ); result.y = (T)( x * sine + y * cosine ); return result; } //! Ermittelt den Winkel zwischen zwei Vektoren inline T angle( const Vec2 &v2 ) const { return (T)lowPrecisionACos( MIN( MAX( (float)( *this * v2 ) / (float)sqrt( (float)( getLengthSq() * v2.getLengthSq() ) ), -1 ), 1 ) ); } }; } #endif