www.pudn.com > ZFXMath-latest.zip > Vector3D.h


/// \file
///
/// \if DE
/// @brief TVector3D
///
/// TVector3D: 3-dimensionaler Vektor
/// \else
/// @brief TVector3D
///
/// TVector3D: 3-dimensional Vector
/// \endif


#ifndef _ZFXMATH_INCLUDE_VECTOR3D_H_
#define _ZFXMATH_INCLUDE_VECTOR3D_H_

namespace ZFXMath
{

	template
	struct TVector4D;

	/// \if DE
	/// @brief TVector3D
	///
	/// TVector3D: 3-dimensionaler Vektor
	/// Hat zusätzlich Color-Funktionaliät (r, g, b)
	/// \else
	/// @brief TVector3D
	///
	/// TVector3D: 3-dimensional Vector
	/// Contains additional color functionality (r, g, b)
	/// \endif
	template
	struct TVector3D
	{
		union
		{
			T			val[3];
			struct
			{
				T		x, y, z;
			};
			struct
			{
				T		r, g, b;
			};
		};

		TVector3D() {};

		TVector3D( const T& _x, const T& _y, const T& _z ) { x=_x; y=_y; z=_z; }

		TVector3D( const T* pV ) { x = pV[0]; y = pV[1]; z = pV[2]; }
		TVector3D( const T& val ) { x = y = z = val; }
		TVector3D( const TVector3D& v ) { x = v.x; y = v.y; z = v.z; }
		TVector3D( const TVector2D& v, const T& _z ) { x = v.x; y = v.y; z = _z; }
		TVector3D( const TVector4D& v ) { x = v.x; y = v.y; z = v.z; }


		/// \if DE
		/// @brief Caste in ein Array von T
		/// \else
		/// @brief Cast to an Array of T
		/// \endif
		operator T* ()	{ return val; }
		operator const T* () const { return val; }

		/// \if DE
		/// @brief Konstanter Zugriff über Index
		/// \else
		/// @brief Const accessors by index
		/// \endif
		T operator () ( const int i ) const
		{
			return val[ Check( i ) ];
		}

		/// \if DE
		/// @brief Nichtkonstanter Zugriff über Index
		/// \else
		/// @brief Non-const accessors by index
		/// \endif
		T& operator () ( const int i )
		{
			return val[ Check( i ) ];
		}

		/// \if DE
		/// @brief Zuweisungsoperator
		/// \else
		/// @brief Assignment operator
		/// \endif
		TVector3D& operator = ( const T& val ) { x = y = z = val; return *this; }
		TVector3D& operator += ( const TVector3D& v ) { x += v.x; y += v.y; z += v.z; return *this; }
		TVector3D& operator -= ( const TVector3D& v ) { x -= v.x; y -= v.y; z -= v.z; return *this; }
		TVector3D& operator *= ( const TVector3D& v ) { x *= v.x; y *= v.y; z *= v.z; return *this; }
		TVector3D& operator /= ( const TVector3D& v ) { x /= v.x; y /= v.y; z /= v.z; return *this; }

		/// \if DE
		/// @brief Zuweisungsoperator (Skalierung)
		/// \else
		/// @brief Assignment operator (scale)
		/// \endif
		TVector3D& operator *= ( const T& v ) { x *= v; y *= v; z *= v; return *this; }
		TVector3D& operator /= ( const T& v ) { x /= v; y /= v; z /= v; return *this; }

		/// \if DE
		/// @brief Unary Operator
		/// \else
		/// @brief Unary operator
		/// \endif
		TVector3D operator + () const { return *this; }
		TVector3D operator - () const { return TVector3D(-x,-y,-z); }

		/// \if DE
		/// @brief Binärer Operator
		/// \else
		/// @brief Binary operator
		/// \endif
		TVector3D operator + ( const TVector3D& v ) const { return TVector3D( x + v.x, y + v.y, z + v.z ); }
		TVector3D operator - ( const TVector3D& v ) const { return TVector3D( x - v.x, y - v.y, z - v.z ); }
		TVector3D operator * ( const TVector3D& v ) const { return TVector3D( x * v.x, y * v.y, z * v.z ); }
		TVector3D operator / ( const TVector3D& v ) const { return TVector3D( x / v.x, y / v.y, z / v.z ); }
		TVector3D operator * ( const T& v ) const { return TVector3D( x * v, y * v, z * v ); }
		TVector3D operator / ( const T& v ) const { return TVector3D( x / v, y / v, z / v ); }
		friend TVector3D operator * ( const T& val, const TVector3D& vec ) { return TVector3D( vec.x * val, vec.y * val, vec.z * val ); }

		/// \if DE
		/// @brief packt die Color in einen unsigned long
		/// \else
		/// @brief packs the color into unsigned long
		/// \endif
		unsigned long ColorToDWORD( T alpha = 1.0 )
		{
			ARGB color( r, g, b, alpha );

			return color;
		};

		/// \if DE
		/// @brief packt den Vektor in einen unsigned long
		/// \else
		/// @brief packs the vector into unsigned long
		/// \endif
		unsigned long ToDWORD( T w = 0.0 )
		{
			ARGB packedVector(  x * 0.5 + 0.5,
								y * 0.5 + 0.5,
								z * 0.5 + 0.5,
								w * 0.5 + 0.5 );

			return packedVector;
		};

		/// \if DE
		/// @brief Quadrat der Länge des Vektors
		/// \else
		/// @brief Square of the length
		/// \endif
		T LengthSqr()
		{
			return DotProduct( *this );
		};

		/// \if DE
		/// @brief Länge des Vektors
		/// \else
		/// @brief length of the vector
		/// \endif
		T Length()
		{
			return Sqrt( LengthSqr() );
		};

		/// \if DE
		/// @brief Normalisiert den Vektor
		///
		/// Vektor wird normalisiert
		/// d.h. er wird auf die Länge 1 skaliert
		/// \else
		/// @brief Normalizes the vector
		///
		/// Vector gets normalized
		/// i.e. it gets scaled to length of 1
		/// \endif
		TVector3D& Normalize()
		{
			return (*this) /= Length();
		};

		/// \if DE
		/// @brief Skalarprodukt
		/// \else
		/// @brief Dotproduct
		/// \endif
		T DotProduct( const TVector3D& v ) const { return v.x * x + v.y * y + v.z * z; }

		/// \if DE
		/// @brief Helligkeit (Vektor als Farbe)
		/// \else
		/// @brief Luminance (vector as color)
		/// \endif
		T Luminance() const { return DotProduct( TVector3D( T(0.39), T(0.5), T(0.11) ) ); }

 
		/// \if DE
		/// @brief Gibt den reflektierten Vektor zurück
		///
		/// \param n Normale der reflektierenden Oberfläche
		/// \else
		/// @brief Returns the reflected vector
		///
		/// \param n normal of the reflecting surface
		/// \endif
		TVector3D Reflect( const TVector3D& n ) const
		{
			return TVector3D( (*this) - 2 * DotProduct( n ) * n );
		}

		/// \if DE
		/// @brief Gibt den gebrochenen Vektor zurück
		///
		/// \param n Normale der brechenden Oberfläche
		/// \param ri Brechungsindex der brechenden Oberfläche
		/// \else
		/// @brief Returns the refracted vector
		///
		/// \param n normal of the refracting surface
		/// \param ri Refraction Index of the refracting surface
		/// \endif
		TVector3D Refract( const TVector3D& n, const T& ri ) const
		{
			T cos = DotProduct( n ) * ri;

			return Interpolate( (*this),  n, cos ).Normalize();
		}

	private:
		inline int Check( const int index ) const
		{
			// Check bounds in debug build
			assert( index >= 0 && index < 3 );

			return (index);
		}
	};
}

#endif //_ZFXMATH_INCLUDE_VECTOR3D_H_