1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102 |
- /*
- *
- * Mathematics Subpackage (VrMath)
- *
- *
- * Author: Samuel R. Buss, [email protected].
- * Web page: http://math.ucsd.edu/~sbuss/MathCG
- *
- *
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it freely,
- subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- *
- *
- */
- //
- // Linear Algebra Classes over R4
- //
- //
- // A. Vector and Position classes
- //
- // A.1. VectorR4: a column vector of length 4
- //
- // B. Matrix Classes
- //
- // B.1 LinearMapR4 - arbitrary linear map; 4x4 real matrix
- //
- // B.2 RotationMapR4 - orthonormal 4x4 matrix
- //
- #ifndef LINEAR_R4_H
- #define LINEAR_R4_H
- #include <math.h>
- #include <assert.h>
- #include <iostream>
- #include "LinearR3.h"
- using namespace std;
- class VectorR4; // R4 Vector
- class LinearMapR4; // 4x4 real matrix
- class RotationMapR4; // 4x4 rotation map
- // **************************************
- // VectorR4 class *
- // * * * * * * * * * * * * * * * * * * **
- class VectorR4 {
- public:
- double x, y, z, w; // The x & y & z & w coordinates.
- static const VectorR4 Zero;
- static const VectorR4 UnitX;
- static const VectorR4 UnitY;
- static const VectorR4 UnitZ;
- static const VectorR4 UnitW;
- static const VectorR4 NegUnitX;
- static const VectorR4 NegUnitY;
- static const VectorR4 NegUnitZ;
- static const VectorR4 NegUnitW;
- public:
- VectorR4( ) : x(0.0), y(0.0), z(0.0), w(0.0) {}
- VectorR4( double xVal, double yVal, double zVal, double wVal )
- : x(xVal), y(yVal), z(zVal), w(wVal) {}
- VectorR4( const Quaternion& q); // Definition with Quaternion routines
-
- VectorR4& SetZero() { x=0.0; y=0.0; z=0.0; w=0.0; return *this;}
- VectorR4& Set( double xx, double yy, double zz, double ww )
- { x=xx; y=yy; z=zz; w=ww; return *this;}
- VectorR4& Set ( const Quaternion& ); // Defined with Quaternion
- VectorR4& Set ( const VectorHgR3& h ) {x=h.x; y=h.y; z=h.z; w=h.w; return *this; }
- VectorR4& Load( const double* v );
- VectorR4& Load( const float* v );
- void Dump( double* v ) const;
- void Dump( float* v ) const;
- VectorR4& operator+= ( const VectorR4& v )
- { x+=v.x; y+=v.y; z+=v.z; w+=v.w; return(*this); }
- VectorR4& operator-= ( const VectorR4& v )
- { x-=v.x; y-=v.y; z-=v.z; w-=v.w; return(*this); }
- VectorR4& operator*= ( double m )
- { x*=m; y*=m; z*=m; w*=m; return(*this); }
- VectorR4& operator/= ( double m )
- { register double mInv = 1.0/m;
- x*=mInv; y*=mInv; z*=mInv; w*=mInv;
- return(*this); }
- VectorR4 operator- () const { return ( VectorR4(-x, -y, -z, -w) ); }
- VectorR4& ArrayProd(const VectorR4&); // Component-wise product
- VectorR4& ArrayProd3(const VectorR3&); // Component-wise product
- VectorR4& AddScaled( const VectorR4& u, double s );
- double Norm() const { return ( (double)sqrt( x*x + y*y + z*z +w*w) ); }
- double NormSq() const { return ( x*x + y*y + z*z + w*w ); }
- double Dist( const VectorR4& u ) const; // Distance from u
- double DistSq( const VectorR4& u ) const; // Distance from u
- double MaxAbs() const;
- VectorR4& Normalize () { *this /= Norm(); return *this; } // No error checking
- inline VectorR4& MakeUnit(); // Normalize() with error checking
- inline VectorR4& ReNormalize();
- bool IsUnit( ) const
- { register double norm = Norm();
- return ( 1.000001>=norm && norm>=0.999999 ); }
- bool IsUnit( double tolerance ) const
- { register double norm = Norm();
- return ( 1.0+tolerance>=norm && norm>=1.0-tolerance ); }
- bool IsZero() const { return ( x==0.0 && y==0.0 && z==0.0 && w==0.0); }
- bool NearZero(double tolerance) const { return( MaxAbs()<=tolerance );}
- // tolerance should be non-negative
- VectorR4& RotateUnitInDirection ( const VectorR4& dir); // rotate in direction dir
- };
- inline VectorR4 operator+( const VectorR4& u, const VectorR4& v );
- inline VectorR4 operator-( const VectorR4& u, const VectorR4& v );
- inline VectorR4 operator*( const VectorR4& u, double m);
- inline VectorR4 operator*( double m, const VectorR4& u);
- inline VectorR4 operator/( const VectorR4& u, double m);
- inline int operator==( const VectorR4& u, const VectorR4& v );
- inline double operator^ (const VectorR4& u, const VectorR4& v ); // Dot Product
- inline VectorR4 ArrayProd(const VectorR4& u, const VectorR4& v );
- inline double Mag(const VectorR4& u) { return u.Norm(); }
- inline double Dist(const VectorR4& u, const VectorR4& v) { return u.Dist(v); }
- inline double DistSq(const VectorR4& u, const VectorR4& v) { return u.DistSq(v); }
- inline double NormalizeError (const VectorR4& u);
- // ********************************************************************
- // Matrix4x4 - base class for 4x4 matrices *
- // * * * * * * * * * * * * * * * * * * * * * **************************
- class Matrix4x4 {
- public:
- double m11, m12, m13, m14, m21, m22, m23, m24,
- m31, m32, m33, m34, m41, m42, m43, m44;
-
- // Implements a 4x4 matrix: m_i_j - row-i and column-j entry
- static const Matrix4x4 Identity;
- public:
- Matrix4x4();
- Matrix4x4( const VectorR4&, const VectorR4&,
- const VectorR4&, const VectorR4& ); // Sets by columns!
- Matrix4x4( double, double, double, double,
- double, double, double, double,
- double, double, double, double,
- double, double, double, double ); // Sets by columns
- inline void SetIdentity (); // Set to the identity map
- inline void SetZero (); // Set to the zero map
- inline void Set ( const Matrix4x4& ); // Set to the matrix.
- inline void Set( const VectorR4&, const VectorR4&,
- const VectorR4&, const VectorR4& );
- inline void Set( double, double, double, double,
- double, double, double, double,
- double, double, double, double,
- double, double, double, double );
- inline void SetByRows( const VectorR4&, const VectorR4&,
- const VectorR4&, const VectorR4& );
- inline void SetByRows( double, double, double, double,
- double, double, double, double,
- double, double, double, double,
- double, double, double, double );
- inline void SetColumn1 ( double, double, double, double );
- inline void SetColumn2 ( double, double, double, double );
- inline void SetColumn3 ( double, double, double, double );
- inline void SetColumn4 ( double, double, double, double );
- inline void SetColumn1 ( const VectorR4& );
- inline void SetColumn2 ( const VectorR4& );
- inline void SetColumn3 ( const VectorR4& );
- inline void SetColumn4 ( const VectorR4& );
- inline VectorR4 Column1() const;
- inline VectorR4 Column2() const;
- inline VectorR4 Column3() const;
- inline VectorR4 Column4() const;
- inline void SetDiagonal( double, double, double, double );
- inline void SetDiagonal( const VectorR4& );
- inline double Diagonal( int );
- inline void MakeTranspose(); // Transposes it.
- void operator*= (const Matrix4x4& B); // Matrix product
- Matrix4x4& ReNormalize();
- };
- inline VectorR4 operator* ( const Matrix4x4&, const VectorR4& );
- ostream& operator<< ( ostream& os, const Matrix4x4& A );
- // *****************************************
- // LinearMapR4 class *
- // * * * * * * * * * * * * * * * * * * * * *
- class LinearMapR4 : public Matrix4x4 {
- public:
- LinearMapR4();
- LinearMapR4( const VectorR4&, const VectorR4&,
- const VectorR4&, const VectorR4& ); // Sets by columns!
- LinearMapR4( double, double, double, double,
- double, double, double, double,
- double, double, double, double,
- double, double, double, double ); // Sets by columns
- LinearMapR4 ( const Matrix4x4& );
- inline LinearMapR4& operator+= (const LinearMapR4& );
- inline LinearMapR4& operator-= (const LinearMapR4& );
- inline LinearMapR4& operator*= (double);
- inline LinearMapR4& operator/= (double);
- inline LinearMapR4& operator*= (const Matrix4x4& ); // Matrix product
- inline LinearMapR4 Transpose() const;
- double Determinant () const; // Returns the determinant
- LinearMapR4 Inverse() const; // Returns inverse
- LinearMapR4& Invert(); // Converts into inverse.
- VectorR4 Solve(const VectorR4&) const; // Returns solution
- LinearMapR4 PseudoInverse() const; // Returns pseudo-inverse TO DO
- VectorR4 PseudoSolve(const VectorR4&); // Finds least squares solution TO DO
- };
-
- inline LinearMapR4 operator+ (const LinearMapR4&, const LinearMapR4&);
- inline LinearMapR4 operator- (const LinearMapR4&);
- inline LinearMapR4 operator- (const LinearMapR4&, const LinearMapR4&);
- inline LinearMapR4 operator* ( const LinearMapR4&, double);
- inline LinearMapR4 operator* ( double, const LinearMapR4& );
- inline LinearMapR4 operator/ ( const LinearMapR4&, double );
- inline LinearMapR4 operator* ( const Matrix4x4&, const LinearMapR4& );
- inline LinearMapR4 operator* ( const LinearMapR4&, const Matrix4x4& );
- // Matrix product (composition)
- // *******************************************
- // RotationMapR4 class *
- // * * * * * * * * * * * * * * * * * * * * * *
- class RotationMapR4 : public Matrix4x4 {
- public:
- RotationMapR4();
- RotationMapR4( const VectorR4&, const VectorR4&,
- const VectorR4&, const VectorR4& ); // Sets by columns!
- RotationMapR4( double, double, double, double,
- double, double, double, double,
- double, double, double, double,
- double, double, double, double ); // Sets by columns!
- RotationMapR4& SetZero(); // IT IS AN ERROR TO USE THIS FUNCTION!
- inline RotationMapR4& operator*= (const RotationMapR4& ); // Matrix product
- inline RotationMapR4 Transpose() const;
- inline RotationMapR4 Inverse() const { return Transpose(); }; // Returns the transpose
- inline RotationMapR4& Invert() { MakeTranspose(); return *this; }; // Transposes it.
- inline VectorR4 Invert(const VectorR4&) const; // Returns solution
- };
-
- inline RotationMapR4 operator* ( const RotationMapR4&, const RotationMapR4& );
- // Matrix product (composition)
- // ***************************************************************
- // * 4-space vector and matrix utilities (prototypes) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Returns the angle between vectors u and v.
- // Use SolidAngleUnit if both vectors are unit vectors
- inline double SolidAngle( const VectorR4& u, const VectorR4& v);
- inline double SolidAngleUnit( const VectorR4 u, const VectorR4 v );
- // Returns a righthanded orthonormal basis to complement vectors u,v,w.
- // The vectors u,v,w must be unit and orthonormal.
- void GetOrtho( const VectorR4& u, RotationMapR4& rotmap );
- void GetOrtho( const VectorR4& u, const VectorR4& v, RotationMapR4& rotmap );
- void GetOrtho( const VectorR4& u, const VectorR4& v, const VectorR4& w,
- RotationMapR4& rotmap );
- void GetOrtho( int j, RotationMapR4& rotmap); // Mainly for internal use
- // Projections
- inline VectorR4 ProjectToUnit ( const VectorR4& u, const VectorR4& v);
- // Project u onto v
- inline VectorR4 ProjectPerpUnit ( const VectorR4& u, const VectorR4 & v);
- // Project perp to v
- inline VectorR4 ProjectPerpUnitDiff ( const VectorR4& u, const VectorR4& v);
- // v must be a unit vector.
- // Returns the projection of u onto unit v
- inline VectorR4 ProjectToUnit ( const VectorR4& u, const VectorR4& v)
- {
- return (u^v)*v;
- }
- // Returns the projection of u onto the plane perpindicular to the unit vector v
- inline VectorR4 ProjectPerpUnit ( const VectorR4& u, const VectorR4& v)
- {
- return ( u - ((u^v)*v) );
- }
- // Returns the projection of u onto the plane perpindicular to the unit vector v
- // This one is more stable when u and v are nearly equal.
- inline VectorR4 ProjectPerpUnitDiff ( const VectorR4& u, const VectorR4& v)
- {
- VectorR4 ans = u;
- ans -= v;
- ans -= ((ans^v)*v);
- return ans; // ans = (u-v) - ((u-v)^v)*v
- }
- // Projection maps (LinearMapR4's)
- // VectorProjectMap returns map projecting onto a given vector u.
- // u should be a unit vector (otherwise the returned map is
- // scaled according to the magnitude of u.
- inline void VectorProjectMap( const VectorR4& u, LinearMapR4& M )
- {
- double a = u.x*u.y;
- double b = u.x*u.z;
- double c = u.x*u.w;
- double d = u.y*u.z;
- double e = u.y*u.w;
- double f = u.z*u.w;
- M.Set( u.x*u.x, a, b, c,
- a, u.y*u.y, d, e,
- b, d, u.z*u.z, f,
- c, e, f, u.w*u.w );
- }
- inline LinearMapR4 VectorProjectMap( const VectorR4& u )
- {
- LinearMapR4 result;
- VectorProjectMap( u, result );
- return result;
- }
- inline LinearMapR4 PerpProjectMap ( const VectorR4& u );
- // u - must be unit vector.
- LinearMapR4 TimesTranspose( const VectorR4& u, const VectorR4& v); // u * v^T.
- inline void TimesTranspose( const VectorR4& u, const VectorR4& v, LinearMapR4& M);
- // Rotation Maps
- RotationMapR4 RotateToMap( const VectorR4& fromVec, const VectorR4& toVec);
- // fromVec and toVec should be unit vectors
- // ***************************************************************
- // * Stream Output Routines (Prototypes) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ostream& operator<< ( ostream& os, const VectorR4& u );
- // *****************************************************
- // * VectorR4 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- inline VectorR4& VectorR4::Load( const double* v )
- {
- x = *v;
- y = *(v+1);
- z = *(v+2);
- w = *(v+3);
- return *this;
- }
- inline VectorR4& VectorR4::Load( const float* v )
- {
- x = *v;
- y = *(v+1);
- z = *(v+2);
- w = *(v+3);
- return *this;
- }
- inline void VectorR4::Dump( double* v ) const
- {
- *v = x;
- *(v+1) = y;
- *(v+2) = z;
- *(v+3) = w;
- }
- inline void VectorR4::Dump( float* v ) const
- {
- *v = (float)x;
- *(v+1) = (float)y;
- *(v+2) = (float)z;
- *(v+3) = (float)w;
- }
- inline VectorR4& VectorR4::MakeUnit () // Convert to unit vector (or leave zero).
- {
- double nSq = NormSq();
- if (nSq != 0.0) {
- *this /= sqrt(nSq);
- }
- return *this;
- }
- inline VectorR4 operator+( const VectorR4& u, const VectorR4& v )
- {
- return VectorR4(u.x+v.x, u.y+v.y, u.z+v.z, u.w+v.w );
- }
- inline VectorR4 operator-( const VectorR4& u, const VectorR4& v )
- {
- return VectorR4(u.x-v.x, u.y-v.y, u.z-v.z, u.w-v.w);
- }
- inline VectorR4 operator*( const VectorR4& u, register double m)
- {
- return VectorR4( u.x*m, u.y*m, u.z*m, u.w*m );
- }
- inline VectorR4 operator*( register double m, const VectorR4& u)
- {
- return VectorR4( u.x*m, u.y*m, u.z*m, u.w*m );
- }
- inline VectorR4 operator/( const VectorR4& u, double m)
- {
- register double mInv = 1.0/m;
- return VectorR4( u.x*mInv, u.y*mInv, u.z*mInv, u.w*mInv );
- }
- inline int operator==( const VectorR4& u, const VectorR4& v )
- {
- return ( u.x==v.x && u.y==v.y && u.z==v.z && u.w==v.w );
- }
- inline double operator^ ( const VectorR4& u, const VectorR4& v ) // Dot Product
- {
- return ( u.x*v.x + u.y*v.y + u.z*v.z + u.w*v.w );
- }
- inline VectorR4 ArrayProd ( const VectorR4& u, const VectorR4& v )
- {
- return ( VectorR4( u.x*v.x, u.y*v.y, u.z*v.z, u.w*v.w ) );
- }
- inline VectorR4& VectorR4::ArrayProd (const VectorR4& v) // Component-wise Product
- {
- x *= v.x;
- y *= v.y;
- z *= v.z;
- w *= v.w;
- return ( *this );
- }
- inline VectorR4& VectorR4::ArrayProd3 (const VectorR3& v) // Component-wise Product
- {
- x *= v.x;
- y *= v.y;
- z *= v.z;
- return ( *this );
- }
- inline VectorR4& VectorR4::AddScaled( const VectorR4& u, double s )
- {
- x += s*u.x;
- y += s*u.y;
- z += s*u.z;
- w += s*u.w;
- return(*this);
- }
- inline VectorR4& VectorR4::ReNormalize() // Convert near unit back to unit
- {
- double nSq = NormSq();
- register double mFact = 1.0-0.5*(nSq-1.0); // Multiplicative factor
- *this *= mFact;
- return *this;
- }
- inline double NormalizeError (const VectorR4& u)
- {
- register double discrepancy;
- discrepancy = u.x*u.x + u.y*u.y + u.z*u.z + u.w*u.w - 1.0;
- if ( discrepancy < 0.0 ) {
- discrepancy = -discrepancy;
- }
- return discrepancy;
- }
- inline VectorR3& VectorR3::SetFromHg(const VectorR4& v) {
- double wInv = 1.0/v.w;
- x = v.x*wInv;
- y = v.y*wInv;
- z = v.z*wInv;
- return *this;
- }
- inline double VectorR4::Dist( const VectorR4& u ) const // Distance from u
- {
- return sqrt( DistSq(u) );
- }
- inline double VectorR4::DistSq( const VectorR4& u ) const // Distance from u
- {
- return ( (x-u.x)*(x-u.x) + (y-u.y)*(y-u.y) + (z-u.z)*(z-u.z) + (w-u.w)*(w-u.w) );
- }
- // *********************************************************
- // * Matrix4x4 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *****
- inline Matrix4x4::Matrix4x4() {}
- inline Matrix4x4::Matrix4x4( const VectorR4& u, const VectorR4& v,
- const VectorR4& s, const VectorR4& t)
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m41 = u.w;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m42 = v.w;
- m13 = s.x; // Column 3
- m23 = s.y;
- m33 = s.z;
- m43 = s.w;
- m14 = t.x; // Column 4
- m24 = t.y;
- m34 = t.z;
- m44 = t.w;
- }
- inline Matrix4x4::Matrix4x4( double a11, double a21, double a31, double a41,
- double a12, double a22, double a32, double a42,
- double a13, double a23, double a33, double a43,
- double a14, double a24, double a34, double a44)
- // Values specified in column order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- m41 = a41; // Row 4
- m42 = a42;
- m43 = a43;
- m44 = a44;
- }
- /*
- inline Matrix4x4::Matrix4x4 ( const Matrix4x4& A)
- : m11(A.m11), m12(A.m12), m13(A.m13), m14(A.m14),
- m21(A.m21), m22(A.m22), m23(A.m23), m24(A.m24),
- m31(A.m31), m32(A.m32), m33(A.m33), m34(A.m34),
- m41(A.m41), m42(A.m42), m43(A.m43), m44(A.m44) {} */
- inline void Matrix4x4::SetIdentity ( )
- {
- m12 = m13 = m14 =
- m21 = m23 = m24 =
- m31 = m32 = m34 =
- m41 = m42 = m43 = 0.0;
- m11 = m22 = m33 = m44 = 1.0;
- }
- inline void Matrix4x4::Set( const VectorR4& u, const VectorR4& v,
- const VectorR4& s, const VectorR4& t )
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m41 = u.w;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m42 = v.w;
- m13 = s.x; // Column 3
- m23 = s.y;
- m33 = s.z;
- m43 = s.w;
- m14 = t.x; // Column 4
- m24 = t.y;
- m34 = t.z;
- m44 = t.w;
- }
- inline void Matrix4x4::Set( double a11, double a21, double a31, double a41,
- double a12, double a22, double a32, double a42,
- double a13, double a23, double a33, double a43,
- double a14, double a24, double a34, double a44)
- // Values specified in column order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- m41 = a41; // Row 4
- m42 = a42;
- m43 = a43;
- m44 = a44;
- }
-
- inline void Matrix4x4::Set ( const Matrix4x4& M ) // Set to the matrix.
- {
- m11 = M.m11;
- m12 = M.m12;
- m13 = M.m13;
- m14 = M.m14;
- m21 = M.m21;
- m22 = M.m22;
- m23 = M.m23;
- m24 = M.m24;
- m31 = M.m31;
- m32 = M.m32;
- m33 = M.m33;
- m34 = M.m34;
- m41 = M.m41;
- m42 = M.m42;
- m43 = M.m43;
- m44 = M.m44;
- }
- inline void Matrix4x4::SetZero( )
- {
- m11 = m12 = m13 = m14 = m21 = m22 = m23 = m24
- = m31 = m32 = m33 = m34 = m41 = m42 = m43 = m44 = 0.0;
- }
- inline void Matrix4x4::SetByRows( const VectorR4& u, const VectorR4& v,
- const VectorR4& s, const VectorR4& t )
- {
- m11 = u.x; // Row 1
- m12 = u.y;
- m13 = u.z;
- m14 = u.w;
- m21 = v.x; // Row 2
- m22 = v.y;
- m23 = v.z;
- m24 = v.w;
- m31 = s.x; // Row 3
- m32 = s.y;
- m33 = s.z;
- m34 = s.w;
- m41 = t.x; // Row 4
- m42 = t.y;
- m43 = t.z;
- m44 = t.w;
- }
- inline void Matrix4x4::SetByRows( double a11, double a12, double a13, double a14,
- double a21, double a22, double a23, double a24,
- double a31, double a32, double a33, double a34,
- double a41, double a42, double a43, double a44 )
- // Values specified in row order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- m41 = a41; // Row 4
- m42 = a42;
- m43 = a43;
- m44 = a44;
- }
- inline void Matrix4x4::SetColumn1 ( double x, double y, double z, double w)
- {
- m11 = x; m21 = y; m31= z; m41 = w;
- }
- inline void Matrix4x4::SetColumn2 ( double x, double y, double z, double w)
- {
- m12 = x; m22 = y; m32= z; m42 = w;
- }
- inline void Matrix4x4::SetColumn3 ( double x, double y, double z, double w)
- {
- m13 = x; m23 = y; m33= z; m43 = w;
- }
- inline void Matrix4x4::SetColumn4 ( double x, double y, double z, double w)
- {
- m14 = x; m24 = y; m34= z; m44 = w;
- }
- inline void Matrix4x4::SetColumn1 ( const VectorR4& u )
- {
- m11 = u.x; m21 = u.y; m31 = u.z; m41 = u.w;
- }
- inline void Matrix4x4::SetColumn2 ( const VectorR4& u )
- {
- m12 = u.x; m22 = u.y; m32 = u.z; m42 = u.w;
- }
- inline void Matrix4x4::SetColumn3 ( const VectorR4& u )
- {
- m13 = u.x; m23 = u.y; m33 = u.z; m43 = u.w;
- }
- inline void Matrix4x4::SetColumn4 ( const VectorR4& u )
- {
- m14 = u.x; m24 = u.y; m34 = u.z; m44 = u.w;
- }
- VectorR4 Matrix4x4::Column1() const
- {
- return ( VectorR4(m11, m21, m31, m41) );
- }
- VectorR4 Matrix4x4::Column2() const
- {
- return ( VectorR4(m12, m22, m32, m42) );
- }
- VectorR4 Matrix4x4::Column3() const
- {
- return ( VectorR4(m13, m23, m33, m43) );
- }
- VectorR4 Matrix4x4::Column4() const
- {
- return ( VectorR4(m14, m24, m34, m44) );
- }
- inline void Matrix4x4::SetDiagonal( double x, double y,
- double z, double w)
- {
- m11 = x;
- m22 = y;
- m33 = z;
- m44 = w;
- }
- inline void Matrix4x4::SetDiagonal( const VectorR4& u )
- {
- SetDiagonal ( u.x, u.y, u.z, u.w );
- }
- inline double Matrix4x4::Diagonal( int i )
- {
- switch (i) {
- case 0:
- return m11;
- case 1:
- return m22;
- case 2:
- return m33;
- case 3:
- return m44;
- default:
- assert(0);
- return 0.0;
- }
- }
- inline void Matrix4x4::MakeTranspose() // Transposes it.
- {
- register double temp;
- temp = m12;
- m12 = m21;
- m21=temp;
- temp = m13;
- m13 = m31;
- m31 = temp;
- temp = m14;
- m14 = m41;
- m41 = temp;
- temp = m23;
- m23 = m32;
- m32 = temp;
- temp = m24;
- m24 = m42;
- m42 = temp;
- temp = m34;
- m34 = m43;
- m43 = temp;
- }
- inline VectorR4 operator* ( const Matrix4x4& A, const VectorR4& u)
- {
- VectorR4 ret;
- ret.x = A.m11*u.x + A.m12*u.y + A.m13*u.z + A.m14*u.w;
- ret.y = A.m21*u.x + A.m22*u.y + A.m23*u.z + A.m24*u.w;
- ret.z = A.m31*u.x + A.m32*u.y + A.m33*u.z + A.m34*u.w;
- ret.w = A.m41*u.x + A.m42*u.y + A.m43*u.z + A.m44*u.w;
- return ret;
- }
- // ******************************************************
- // * LinearMapR4 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline LinearMapR4::LinearMapR4()
- {
- SetZero();
- return;
- }
- inline LinearMapR4::LinearMapR4( const VectorR4& u, const VectorR4& v,
- const VectorR4& s, const VectorR4& t)
- :Matrix4x4 ( u, v, s ,t )
- { }
- inline LinearMapR4::LinearMapR4(
- double a11, double a21, double a31, double a41,
- double a12, double a22, double a32, double a42,
- double a13, double a23, double a33, double a43,
- double a14, double a24, double a34, double a44)
- // Values specified in column order!!!
- :Matrix4x4 ( a11, a21, a31, a41, a12, a22, a32, a42,
- a13, a23, a33, a43, a14, a24, a34, a44 )
- { }
- inline LinearMapR4::LinearMapR4 ( const Matrix4x4& A )
- : Matrix4x4 (A)
- {}
-
- inline LinearMapR4& LinearMapR4::operator+= (const LinearMapR4& B)
- {
- m11 += B.m11;
- m12 += B.m12;
- m13 += B.m13;
- m14 += B.m14;
- m21 += B.m21;
- m22 += B.m22;
- m23 += B.m23;
- m24 += B.m24;
- m31 += B.m31;
- m32 += B.m32;
- m33 += B.m33;
- m34 += B.m34;
- m41 += B.m41;
- m42 += B.m42;
- m43 += B.m43;
- m44 += B.m44;
- return ( *this );
- }
- inline LinearMapR4& LinearMapR4::operator-= (const LinearMapR4& B)
- {
- m11 -= B.m11;
- m12 -= B.m12;
- m13 -= B.m13;
- m14 -= B.m14;
- m21 -= B.m21;
- m22 -= B.m22;
- m23 -= B.m23;
- m24 -= B.m24;
- m31 -= B.m31;
- m32 -= B.m32;
- m33 -= B.m33;
- m34 -= B.m34;
- m41 -= B.m41;
- m42 -= B.m42;
- m43 -= B.m43;
- m44 -= B.m44;
- return( *this );
- }
- inline LinearMapR4 operator+ (const LinearMapR4& A, const LinearMapR4& B)
- {
- return( LinearMapR4( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31, A.m41+B.m41,
- A.m12+B.m12, A.m22+B.m22, A.m32+B.m32, A.m42+B.m42,
- A.m13+B.m13, A.m23+B.m23, A.m33+B.m33, A.m43+B.m43,
- A.m14+B.m14, A.m24+B.m24, A.m34+B.m34, A.m44+B.m44) );
- }
- inline LinearMapR4 operator- (const LinearMapR4& A)
- {
- return( LinearMapR4( -A.m11, -A.m21, -A.m31, -A.m41,
- -A.m12, -A.m22, -A.m32, -A.m42,
- -A.m13, -A.m23, -A.m33, -A.m43,
- -A.m14, -A.m24, -A.m34, -A.m44 ) );
- }
- inline LinearMapR4 operator- (const LinearMapR4& A, const LinearMapR4& B)
- {
- return( LinearMapR4( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31, A.m41-B.m41,
- A.m12-B.m12, A.m22-B.m22, A.m32-B.m32, A.m42-B.m42,
- A.m13-B.m13, A.m23-B.m23, A.m33-B.m33, A.m43-B.m43,
- A.m14-B.m14, A.m24-B.m24, A.m34-B.m34, A.m44-B.m44 ) );
- }
- inline LinearMapR4& LinearMapR4::operator*= (register double b)
- {
- m11 *= b;
- m12 *= b;
- m13 *= b;
- m14 *= b;
- m21 *= b;
- m22 *= b;
- m23 *= b;
- m24 *= b;
- m31 *= b;
- m32 *= b;
- m33 *= b;
- m34 *= b;
- m41 *= b;
- m42 *= b;
- m43 *= b;
- m44 *= b;
- return ( *this);
- }
- inline LinearMapR4 operator* ( const LinearMapR4& A, register double b)
- {
- return( LinearMapR4( A.m11*b, A.m21*b, A.m31*b, A.m41*b,
- A.m12*b, A.m22*b, A.m32*b, A.m42*b,
- A.m13*b, A.m23*b, A.m33*b, A.m43*b,
- A.m14*b, A.m24*b, A.m34*b, A.m44*b) );
- }
- inline LinearMapR4 operator* ( register double b, const LinearMapR4& A)
- {
- return( LinearMapR4( A.m11*b, A.m21*b, A.m31*b, A.m41*b,
- A.m12*b, A.m22*b, A.m32*b, A.m42*b,
- A.m13*b, A.m23*b, A.m33*b, A.m43*b,
- A.m14*b, A.m24*b, A.m34*b, A.m44*b ) );
- }
- inline LinearMapR4 operator/ ( const LinearMapR4& A, double b)
- {
- register double bInv = 1.0/b;
- return ( A*bInv );
- }
- inline LinearMapR4& LinearMapR4::operator/= (register double b)
- {
- register double bInv = 1.0/b;
- return ( *this *= bInv );
- }
- inline VectorR4 operator* ( const LinearMapR4& A, const VectorR4& u)
- {
- return(VectorR4 ( A.m11*u.x + A.m12*u.y + A.m13*u.z + A.m14*u.w,
- A.m21*u.x + A.m22*u.y + A.m23*u.z + A.m24*u.w,
- A.m31*u.x + A.m32*u.y + A.m33*u.z + A.m34*u.w,
- A.m41*u.x + A.m42*u.y + A.m43*u.z + A.m44*u.w ) );
- }
-
- inline LinearMapR4 LinearMapR4::Transpose() const // Returns the transpose
- {
- return (LinearMapR4( m11, m12, m13, m14,
- m21, m22, m23, m24,
- m31, m32, m33, m34,
- m41, m42, m43, m44 ) );
- }
- inline LinearMapR4& LinearMapR4::operator*= (const Matrix4x4& B) // Matrix product
- {
- (*this).Matrix4x4::operator*=(B);
- return( *this );
- }
- inline LinearMapR4 operator* ( const LinearMapR4& A, const Matrix4x4& B)
- {
- LinearMapR4 AA(A);
- AA.Matrix4x4::operator*=(B);
- return AA;
- }
- inline LinearMapR4 operator* ( const Matrix4x4& A, const LinearMapR4& B)
- {
- LinearMapR4 AA(A);
- AA.Matrix4x4::operator*=(B);
- return AA;
- }
- // ******************************************************
- // * RotationMapR4 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline RotationMapR4::RotationMapR4()
- {
- SetIdentity();
- return;
- }
-
- inline RotationMapR4::RotationMapR4( const VectorR4& u, const VectorR4& v,
- const VectorR4& s, const VectorR4& t)
- :Matrix4x4 ( u, v, s ,t )
- { }
- inline RotationMapR4::RotationMapR4(
- double a11, double a21, double a31, double a41,
- double a12, double a22, double a32, double a42,
- double a13, double a23, double a33, double a43,
- double a14, double a24, double a34, double a44)
- // Values specified in column order!!!
- :Matrix4x4 ( a11, a21, a31, a41, a12, a22, a32, a42,
- a13, a23, a33, a43, a14, a24, a34, a44 )
- { }
- inline RotationMapR4 RotationMapR4::Transpose() const // Returns the transpose
- {
- return ( RotationMapR4( m11, m12, m13, m14,
- m21, m22, m23, m24,
- m31, m32, m33, m34,
- m41, m42, m43, m44 ) );
- }
- inline VectorR4 RotationMapR4::Invert(const VectorR4& u) const // Returns solution
- {
- return (VectorR4( m11*u.x + m21*u.y + m31*u.z + m41*u.w,
- m12*u.x + m22*u.y + m32*u.z + m42*u.w,
- m13*u.x + m23*u.y + m33*u.z + m43*u.w,
- m14*u.x + m24*u.y + m34*u.z + m44*u.w ) );
- }
- inline RotationMapR4& RotationMapR4::operator*= (const RotationMapR4& B) // Matrix product
- {
- (*this).Matrix4x4::operator*=(B);
- return( *this );
- }
- inline RotationMapR4 operator* ( const RotationMapR4& A, const RotationMapR4& B)
- {
- RotationMapR4 AA(A);
- AA.Matrix4x4::operator*=(B);
- return AA;
- }
- // ***************************************************************
- // * 4-space vector and matrix utilities (inlined functions) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- inline void TimesTranspose( const VectorR4& u, const VectorR4& v, LinearMapR4& M)
- {
- M.Set ( v.x*u.x, v.x*u.y, v.x*u.z, v.x*u.w, // Set by columns!
- v.y*u.x, v.y*u.y, v.y*u.z, v.y*u.w,
- v.z*u.x, v.z*u.y, v.z*u.z, v.z*u.w,
- v.w*u.x, v.w*u.y, v.w*u.z, v.w*u.w ) ;
- }
- // Returns the solid angle between vectors u and v (not necessarily unit vectors)
- inline double SolidAngle( const VectorR4& u, const VectorR4& v)
- {
- double nSqU = u.NormSq();
- double nSqV = v.NormSq();
- if ( nSqU==0.0 && nSqV==0.0 ) {
- return (0.0);
- }
- else {
- return ( SolidAngleUnit( u/sqrt(nSqU), v/sqrt(nSqV) ) );
- }
- }
- inline double SolidAngleUnit( const VectorR4 u, const VectorR4 v )
- {
- return ( atan2 ( ProjectPerpUnit(v,u).Norm(), u^v ) );
- }
- #endif // LINEAR_R4_H
|