/*************************************************************************** * Vec4.h * * * * Basic operations on 4-dimensional vectors. This special case is useful * * because many operations are performed inline. * * * * HISTORY * * Name Date Description * * * * walt 6/26/07 Edited Vec3 to make this new class * * arvo 10/27/94 Reorganized (removed Col & Row distinction). * * arvo 06/14/93 Initial coding. * * * *--------------------------------------------------------------------------* * Copyright (C) 1994, James Arvo * * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the * * Free Software Foundation. See http://www.fsf.org/copyleft/gpl.html * * * * This program is distributed in the hope that it will be useful, but * * WITHOUT EXPRESS OR IMPLIED WARRANTY of merchantability or fitness for * * any particular purpose. See the GNU General Public License for more * * details. * * * ***************************************************************************/ #ifndef __Vec4_INCLUDED__ #define __Vec4_INCLUDED__ #include #include #include "Vec2.h" #include "Vec3.h" namespace ArvoMath { class Vec4 { public: Vec4( float c = 0.0 ) { x = c; y = c; z = c; w = c; } Vec4( float a, float b, float c, float d ) { x = a; y = b; z = c; w = d; } Vec4( const Vec4 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = A.W(); } Vec4( const Vec3 &A, float d ) { x = A.X(); y = A.Y(); z = A.Z(); w = d; } void operator=( float c ) { x = c; y = c; z = c; w = c; } void operator=( const Vec4 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = A.W(); } void operator=( const Vec3 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = 0.0; } void operator=( const Vec2 &A ) { x = A.X(); y = A.Y(); z = 0.0; w = 0.0; } ~Vec4() {} float X() const { return x; } float Y() const { return y; } float Z() const { return z; } float W() const { return w; } float & X() { return x; } float & Y() { return y; } float & Z() { return z; } float & W() { return w; } float operator[]( int i ) const { return *( &x + i ); } float & operator[]( int i ) { return *( &x + i ); } private: float x, y, z, w; }; //========================================== //=== Norm-related functions === //========================================== inline double LenSqr ( const Vec4 &A ) { return Sqr(A[0]) + Sqr(A[1]) + Sqr(A[2]) + Sqr(A[3]); } inline double Len ( const Vec4 &A ) { return Sqrt( LenSqr( A ) ); } inline double Norm1 ( const Vec4 &A ) { return Abs(A[0]) + Abs(A[1]) + Abs(A[2]) + Abs(A[3]); } inline double Norm2 ( const Vec4 &A ) { return Len( A ); } inline float SupNorm( const Vec4 &A ) { return MaxAbs( A[0], A[1], A[2], A[3] ); } //========================================== //=== Addition === //========================================== inline Vec4 operator+( const Vec4 &A, const Vec4 &B ) { return Vec4( A.X() + B.X(), A.Y() + B.Y(), A.Z() + B.Z(), A.W() + B.W() ); } inline Vec4& operator+=( Vec4 &A, const Vec4 &B ) { A.X() += B.X(); A.Y() += B.Y(); A.Z() += B.Z(); A.W() += B.W(); return A; } //========================================== //=== Subtraction === //========================================== inline Vec4 operator-( const Vec4 &A, const Vec4 &B ) { return Vec4( A.X() - B.X(), A.Y() - B.Y(), A.Z() - B.Z(), A.W() - B.W()); } inline Vec4 operator-( const Vec4 &A ) { return Vec4( -A.X(), -A.Y(), -A.Z(), -A.W() ); } inline Vec4& operator-=( Vec4 &A, const Vec4 &B ) { A.X() -= B.X(); A.Y() -= B.Y(); A.Z() -= B.Z(); A.W() -= B.W(); return A; } //========================================== //=== Multiplication === //========================================== inline Vec4 operator*( float a, const Vec4 &x ) { return Vec4( a * x.X(), a * x.Y(), a * x.Z(), a * x.W() ); } inline Vec4 operator*( const Vec4 &x, float a ) { return Vec4( a * x.X(), a * x.Y(), a * x.Z(), a * x.W() ); } inline float operator*( const Vec4 &A, const Vec4 &B ) // Inner product. { return A.X() * B.X() + A.Y() * B.Y() + A.Z() * B.Z() + A.W() * B.W(); } inline Vec4& operator*=( Vec4 &A, float a ) { A.X() *= a; A.Y() *= a; A.Z() *= a; A.W() *= a; return A; } //========================================== //=== Division === //========================================== inline Vec4 operator/( const Vec4 &A, double c ) { double t = 1.0 / c; return Vec4( A.X() * t, A.Y() * t, A.Z() * t, A.W() * t); } inline Vec4& operator/=( Vec4 &A, double a ) { A.X() /= a; A.Y() /= a; A.Z() /= a; A.W() /= a; return A; } inline Vec4 operator/( const Vec4 &A, const Vec4 &B ) // Remove component parallel to B. { Vec4 C; // Cumbersome due to compiler falure. double x = LenSqr( B ); if( x > 0.0 ) C = A - B * (( A * B ) / x); else C = A; return C; } inline void operator/=( Vec4 &A, const Vec4 &B ) // Remove component parallel to B. { double x = LenSqr( B ); if( x > 0.0 ) A -= B * (( A * B ) / x); } //========================================== //=== Miscellaneous === //========================================== inline float operator|( const Vec4 &A, const Vec4 &B ) // Inner product. { return A * B; } inline Vec4 Unit( const Vec4 &A ) { double d = LenSqr( A ); return d > 0.0 ? A / sqrt(d) : Vec4(0,0,0,0); } inline Vec4 Unit( float x, float y, float z, float w ) { return Unit( Vec4( x, y, z, w ) ); } inline Vec4 Ortho( const Vec4 &A, const Vec4 &B ) { return Unit( A / B ); } inline int operator==( const Vec4 &A, float x ) { return (A[0] == x) && (A[1] == x) && (A[2] == x) && (A[3] == x); } // inline Vec4 operator^( const Vec4 &A, const Vec4 &B ) there is no 4ED "cross product" of 2 4D vectors -- we need six dimensions inline double dist( const Vec4 &A, const Vec4 &B ) { return Len( A - B ); } // inline double Dihedral( const Vec4 &A, const Vec4 &B, const Vec4 &C ) inline Vec4 operator>>( const Vec4 &A, const Vec4 &B ) // Project A onto B. { Vec4 C; double x = LenSqr( B ); if( x > 0.0 ) C = B * (( A * B ) / x); return C; } inline Vec4 operator<<( const Vec4 &A, const Vec4 &B ) // Project B onto A. { return B >> A; } // inline double Triple( const Vec4 &A, const Vec4 &B, const Vec4 &C ) //========================================== //=== Output routines === //========================================== extern std::ostream &operator<<( std::ostream &out, const Vec4 & ); }; #endif