LinearR4.h 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102
  1. /*
  2. *
  3. * Mathematics Subpackage (VrMath)
  4. *
  5. *
  6. * Author: Samuel R. Buss, [email protected].
  7. * Web page: http://math.ucsd.edu/~sbuss/MathCG
  8. *
  9. *
  10. This software is provided 'as-is', without any express or implied warranty.
  11. In no event will the authors be held liable for any damages arising from the use of this software.
  12. Permission is granted to anyone to use this software for any purpose,
  13. including commercial applications, and to alter it and redistribute it freely,
  14. subject to the following restrictions:
  15. 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.
  16. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  17. 3. This notice may not be removed or altered from any source distribution.
  18. *
  19. *
  20. */
  21. //
  22. // Linear Algebra Classes over R4
  23. //
  24. //
  25. // A. Vector and Position classes
  26. //
  27. // A.1. VectorR4: a column vector of length 4
  28. //
  29. // B. Matrix Classes
  30. //
  31. // B.1 LinearMapR4 - arbitrary linear map; 4x4 real matrix
  32. //
  33. // B.2 RotationMapR4 - orthonormal 4x4 matrix
  34. //
  35. #ifndef LINEAR_R4_H
  36. #define LINEAR_R4_H
  37. #include <math.h>
  38. #include <assert.h>
  39. #include <iostream>
  40. #include "LinearR3.h"
  41. using namespace std;
  42. class VectorR4; // R4 Vector
  43. class LinearMapR4; // 4x4 real matrix
  44. class RotationMapR4; // 4x4 rotation map
  45. // **************************************
  46. // VectorR4 class *
  47. // * * * * * * * * * * * * * * * * * * **
  48. class VectorR4 {
  49. public:
  50. double x, y, z, w; // The x & y & z & w coordinates.
  51. static const VectorR4 Zero;
  52. static const VectorR4 UnitX;
  53. static const VectorR4 UnitY;
  54. static const VectorR4 UnitZ;
  55. static const VectorR4 UnitW;
  56. static const VectorR4 NegUnitX;
  57. static const VectorR4 NegUnitY;
  58. static const VectorR4 NegUnitZ;
  59. static const VectorR4 NegUnitW;
  60. public:
  61. VectorR4( ) : x(0.0), y(0.0), z(0.0), w(0.0) {}
  62. VectorR4( double xVal, double yVal, double zVal, double wVal )
  63. : x(xVal), y(yVal), z(zVal), w(wVal) {}
  64. VectorR4( const Quaternion& q); // Definition with Quaternion routines
  65. VectorR4& SetZero() { x=0.0; y=0.0; z=0.0; w=0.0; return *this;}
  66. VectorR4& Set( double xx, double yy, double zz, double ww )
  67. { x=xx; y=yy; z=zz; w=ww; return *this;}
  68. VectorR4& Set ( const Quaternion& ); // Defined with Quaternion
  69. VectorR4& Set ( const VectorHgR3& h ) {x=h.x; y=h.y; z=h.z; w=h.w; return *this; }
  70. VectorR4& Load( const double* v );
  71. VectorR4& Load( const float* v );
  72. void Dump( double* v ) const;
  73. void Dump( float* v ) const;
  74. VectorR4& operator+= ( const VectorR4& v )
  75. { x+=v.x; y+=v.y; z+=v.z; w+=v.w; return(*this); }
  76. VectorR4& operator-= ( const VectorR4& v )
  77. { x-=v.x; y-=v.y; z-=v.z; w-=v.w; return(*this); }
  78. VectorR4& operator*= ( double m )
  79. { x*=m; y*=m; z*=m; w*=m; return(*this); }
  80. VectorR4& operator/= ( double m )
  81. { register double mInv = 1.0/m;
  82. x*=mInv; y*=mInv; z*=mInv; w*=mInv;
  83. return(*this); }
  84. VectorR4 operator- () const { return ( VectorR4(-x, -y, -z, -w) ); }
  85. VectorR4& ArrayProd(const VectorR4&); // Component-wise product
  86. VectorR4& ArrayProd3(const VectorR3&); // Component-wise product
  87. VectorR4& AddScaled( const VectorR4& u, double s );
  88. double Norm() const { return ( (double)sqrt( x*x + y*y + z*z +w*w) ); }
  89. double NormSq() const { return ( x*x + y*y + z*z + w*w ); }
  90. double Dist( const VectorR4& u ) const; // Distance from u
  91. double DistSq( const VectorR4& u ) const; // Distance from u
  92. double MaxAbs() const;
  93. VectorR4& Normalize () { *this /= Norm(); return *this; } // No error checking
  94. inline VectorR4& MakeUnit(); // Normalize() with error checking
  95. inline VectorR4& ReNormalize();
  96. bool IsUnit( ) const
  97. { register double norm = Norm();
  98. return ( 1.000001>=norm && norm>=0.999999 ); }
  99. bool IsUnit( double tolerance ) const
  100. { register double norm = Norm();
  101. return ( 1.0+tolerance>=norm && norm>=1.0-tolerance ); }
  102. bool IsZero() const { return ( x==0.0 && y==0.0 && z==0.0 && w==0.0); }
  103. bool NearZero(double tolerance) const { return( MaxAbs()<=tolerance );}
  104. // tolerance should be non-negative
  105. VectorR4& RotateUnitInDirection ( const VectorR4& dir); // rotate in direction dir
  106. };
  107. inline VectorR4 operator+( const VectorR4& u, const VectorR4& v );
  108. inline VectorR4 operator-( const VectorR4& u, const VectorR4& v );
  109. inline VectorR4 operator*( const VectorR4& u, double m);
  110. inline VectorR4 operator*( double m, const VectorR4& u);
  111. inline VectorR4 operator/( const VectorR4& u, double m);
  112. inline int operator==( const VectorR4& u, const VectorR4& v );
  113. inline double operator^ (const VectorR4& u, const VectorR4& v ); // Dot Product
  114. inline VectorR4 ArrayProd(const VectorR4& u, const VectorR4& v );
  115. inline double Mag(const VectorR4& u) { return u.Norm(); }
  116. inline double Dist(const VectorR4& u, const VectorR4& v) { return u.Dist(v); }
  117. inline double DistSq(const VectorR4& u, const VectorR4& v) { return u.DistSq(v); }
  118. inline double NormalizeError (const VectorR4& u);
  119. // ********************************************************************
  120. // Matrix4x4 - base class for 4x4 matrices *
  121. // * * * * * * * * * * * * * * * * * * * * * **************************
  122. class Matrix4x4 {
  123. public:
  124. double m11, m12, m13, m14, m21, m22, m23, m24,
  125. m31, m32, m33, m34, m41, m42, m43, m44;
  126. // Implements a 4x4 matrix: m_i_j - row-i and column-j entry
  127. static const Matrix4x4 Identity;
  128. public:
  129. Matrix4x4();
  130. Matrix4x4( const VectorR4&, const VectorR4&,
  131. const VectorR4&, const VectorR4& ); // Sets by columns!
  132. Matrix4x4( double, double, double, double,
  133. double, double, double, double,
  134. double, double, double, double,
  135. double, double, double, double ); // Sets by columns
  136. inline void SetIdentity (); // Set to the identity map
  137. inline void SetZero (); // Set to the zero map
  138. inline void Set ( const Matrix4x4& ); // Set to the matrix.
  139. inline void Set( const VectorR4&, const VectorR4&,
  140. const VectorR4&, const VectorR4& );
  141. inline void Set( double, double, double, double,
  142. double, double, double, double,
  143. double, double, double, double,
  144. double, double, double, double );
  145. inline void SetByRows( const VectorR4&, const VectorR4&,
  146. const VectorR4&, const VectorR4& );
  147. inline void SetByRows( double, double, double, double,
  148. double, double, double, double,
  149. double, double, double, double,
  150. double, double, double, double );
  151. inline void SetColumn1 ( double, double, double, double );
  152. inline void SetColumn2 ( double, double, double, double );
  153. inline void SetColumn3 ( double, double, double, double );
  154. inline void SetColumn4 ( double, double, double, double );
  155. inline void SetColumn1 ( const VectorR4& );
  156. inline void SetColumn2 ( const VectorR4& );
  157. inline void SetColumn3 ( const VectorR4& );
  158. inline void SetColumn4 ( const VectorR4& );
  159. inline VectorR4 Column1() const;
  160. inline VectorR4 Column2() const;
  161. inline VectorR4 Column3() const;
  162. inline VectorR4 Column4() const;
  163. inline void SetDiagonal( double, double, double, double );
  164. inline void SetDiagonal( const VectorR4& );
  165. inline double Diagonal( int );
  166. inline void MakeTranspose(); // Transposes it.
  167. void operator*= (const Matrix4x4& B); // Matrix product
  168. Matrix4x4& ReNormalize();
  169. };
  170. inline VectorR4 operator* ( const Matrix4x4&, const VectorR4& );
  171. ostream& operator<< ( ostream& os, const Matrix4x4& A );
  172. // *****************************************
  173. // LinearMapR4 class *
  174. // * * * * * * * * * * * * * * * * * * * * *
  175. class LinearMapR4 : public Matrix4x4 {
  176. public:
  177. LinearMapR4();
  178. LinearMapR4( const VectorR4&, const VectorR4&,
  179. const VectorR4&, const VectorR4& ); // Sets by columns!
  180. LinearMapR4( double, double, double, double,
  181. double, double, double, double,
  182. double, double, double, double,
  183. double, double, double, double ); // Sets by columns
  184. LinearMapR4 ( const Matrix4x4& );
  185. inline LinearMapR4& operator+= (const LinearMapR4& );
  186. inline LinearMapR4& operator-= (const LinearMapR4& );
  187. inline LinearMapR4& operator*= (double);
  188. inline LinearMapR4& operator/= (double);
  189. inline LinearMapR4& operator*= (const Matrix4x4& ); // Matrix product
  190. inline LinearMapR4 Transpose() const;
  191. double Determinant () const; // Returns the determinant
  192. LinearMapR4 Inverse() const; // Returns inverse
  193. LinearMapR4& Invert(); // Converts into inverse.
  194. VectorR4 Solve(const VectorR4&) const; // Returns solution
  195. LinearMapR4 PseudoInverse() const; // Returns pseudo-inverse TO DO
  196. VectorR4 PseudoSolve(const VectorR4&); // Finds least squares solution TO DO
  197. };
  198. inline LinearMapR4 operator+ (const LinearMapR4&, const LinearMapR4&);
  199. inline LinearMapR4 operator- (const LinearMapR4&);
  200. inline LinearMapR4 operator- (const LinearMapR4&, const LinearMapR4&);
  201. inline LinearMapR4 operator* ( const LinearMapR4&, double);
  202. inline LinearMapR4 operator* ( double, const LinearMapR4& );
  203. inline LinearMapR4 operator/ ( const LinearMapR4&, double );
  204. inline LinearMapR4 operator* ( const Matrix4x4&, const LinearMapR4& );
  205. inline LinearMapR4 operator* ( const LinearMapR4&, const Matrix4x4& );
  206. // Matrix product (composition)
  207. // *******************************************
  208. // RotationMapR4 class *
  209. // * * * * * * * * * * * * * * * * * * * * * *
  210. class RotationMapR4 : public Matrix4x4 {
  211. public:
  212. RotationMapR4();
  213. RotationMapR4( const VectorR4&, const VectorR4&,
  214. const VectorR4&, const VectorR4& ); // Sets by columns!
  215. RotationMapR4( double, double, double, double,
  216. double, double, double, double,
  217. double, double, double, double,
  218. double, double, double, double ); // Sets by columns!
  219. RotationMapR4& SetZero(); // IT IS AN ERROR TO USE THIS FUNCTION!
  220. inline RotationMapR4& operator*= (const RotationMapR4& ); // Matrix product
  221. inline RotationMapR4 Transpose() const;
  222. inline RotationMapR4 Inverse() const { return Transpose(); }; // Returns the transpose
  223. inline RotationMapR4& Invert() { MakeTranspose(); return *this; }; // Transposes it.
  224. inline VectorR4 Invert(const VectorR4&) const; // Returns solution
  225. };
  226. inline RotationMapR4 operator* ( const RotationMapR4&, const RotationMapR4& );
  227. // Matrix product (composition)
  228. // ***************************************************************
  229. // * 4-space vector and matrix utilities (prototypes) *
  230. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  231. // Returns the angle between vectors u and v.
  232. // Use SolidAngleUnit if both vectors are unit vectors
  233. inline double SolidAngle( const VectorR4& u, const VectorR4& v);
  234. inline double SolidAngleUnit( const VectorR4 u, const VectorR4 v );
  235. // Returns a righthanded orthonormal basis to complement vectors u,v,w.
  236. // The vectors u,v,w must be unit and orthonormal.
  237. void GetOrtho( const VectorR4& u, RotationMapR4& rotmap );
  238. void GetOrtho( const VectorR4& u, const VectorR4& v, RotationMapR4& rotmap );
  239. void GetOrtho( const VectorR4& u, const VectorR4& v, const VectorR4& w,
  240. RotationMapR4& rotmap );
  241. void GetOrtho( int j, RotationMapR4& rotmap); // Mainly for internal use
  242. // Projections
  243. inline VectorR4 ProjectToUnit ( const VectorR4& u, const VectorR4& v);
  244. // Project u onto v
  245. inline VectorR4 ProjectPerpUnit ( const VectorR4& u, const VectorR4 & v);
  246. // Project perp to v
  247. inline VectorR4 ProjectPerpUnitDiff ( const VectorR4& u, const VectorR4& v);
  248. // v must be a unit vector.
  249. // Returns the projection of u onto unit v
  250. inline VectorR4 ProjectToUnit ( const VectorR4& u, const VectorR4& v)
  251. {
  252. return (u^v)*v;
  253. }
  254. // Returns the projection of u onto the plane perpindicular to the unit vector v
  255. inline VectorR4 ProjectPerpUnit ( const VectorR4& u, const VectorR4& v)
  256. {
  257. return ( u - ((u^v)*v) );
  258. }
  259. // Returns the projection of u onto the plane perpindicular to the unit vector v
  260. // This one is more stable when u and v are nearly equal.
  261. inline VectorR4 ProjectPerpUnitDiff ( const VectorR4& u, const VectorR4& v)
  262. {
  263. VectorR4 ans = u;
  264. ans -= v;
  265. ans -= ((ans^v)*v);
  266. return ans; // ans = (u-v) - ((u-v)^v)*v
  267. }
  268. // Projection maps (LinearMapR4's)
  269. // VectorProjectMap returns map projecting onto a given vector u.
  270. // u should be a unit vector (otherwise the returned map is
  271. // scaled according to the magnitude of u.
  272. inline void VectorProjectMap( const VectorR4& u, LinearMapR4& M )
  273. {
  274. double a = u.x*u.y;
  275. double b = u.x*u.z;
  276. double c = u.x*u.w;
  277. double d = u.y*u.z;
  278. double e = u.y*u.w;
  279. double f = u.z*u.w;
  280. M.Set( u.x*u.x, a, b, c,
  281. a, u.y*u.y, d, e,
  282. b, d, u.z*u.z, f,
  283. c, e, f, u.w*u.w );
  284. }
  285. inline LinearMapR4 VectorProjectMap( const VectorR4& u )
  286. {
  287. LinearMapR4 result;
  288. VectorProjectMap( u, result );
  289. return result;
  290. }
  291. inline LinearMapR4 PerpProjectMap ( const VectorR4& u );
  292. // u - must be unit vector.
  293. LinearMapR4 TimesTranspose( const VectorR4& u, const VectorR4& v); // u * v^T.
  294. inline void TimesTranspose( const VectorR4& u, const VectorR4& v, LinearMapR4& M);
  295. // Rotation Maps
  296. RotationMapR4 RotateToMap( const VectorR4& fromVec, const VectorR4& toVec);
  297. // fromVec and toVec should be unit vectors
  298. // ***************************************************************
  299. // * Stream Output Routines (Prototypes) *
  300. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  301. ostream& operator<< ( ostream& os, const VectorR4& u );
  302. // *****************************************************
  303. // * VectorR4 class - inlined functions *
  304. // * * * * * * * * * * * * * * * * * * * * * * * * * * *
  305. inline VectorR4& VectorR4::Load( const double* v )
  306. {
  307. x = *v;
  308. y = *(v+1);
  309. z = *(v+2);
  310. w = *(v+3);
  311. return *this;
  312. }
  313. inline VectorR4& VectorR4::Load( const float* v )
  314. {
  315. x = *v;
  316. y = *(v+1);
  317. z = *(v+2);
  318. w = *(v+3);
  319. return *this;
  320. }
  321. inline void VectorR4::Dump( double* v ) const
  322. {
  323. *v = x;
  324. *(v+1) = y;
  325. *(v+2) = z;
  326. *(v+3) = w;
  327. }
  328. inline void VectorR4::Dump( float* v ) const
  329. {
  330. *v = (float)x;
  331. *(v+1) = (float)y;
  332. *(v+2) = (float)z;
  333. *(v+3) = (float)w;
  334. }
  335. inline VectorR4& VectorR4::MakeUnit () // Convert to unit vector (or leave zero).
  336. {
  337. double nSq = NormSq();
  338. if (nSq != 0.0) {
  339. *this /= sqrt(nSq);
  340. }
  341. return *this;
  342. }
  343. inline VectorR4 operator+( const VectorR4& u, const VectorR4& v )
  344. {
  345. return VectorR4(u.x+v.x, u.y+v.y, u.z+v.z, u.w+v.w );
  346. }
  347. inline VectorR4 operator-( const VectorR4& u, const VectorR4& v )
  348. {
  349. return VectorR4(u.x-v.x, u.y-v.y, u.z-v.z, u.w-v.w);
  350. }
  351. inline VectorR4 operator*( const VectorR4& u, register double m)
  352. {
  353. return VectorR4( u.x*m, u.y*m, u.z*m, u.w*m );
  354. }
  355. inline VectorR4 operator*( register double m, const VectorR4& u)
  356. {
  357. return VectorR4( u.x*m, u.y*m, u.z*m, u.w*m );
  358. }
  359. inline VectorR4 operator/( const VectorR4& u, double m)
  360. {
  361. register double mInv = 1.0/m;
  362. return VectorR4( u.x*mInv, u.y*mInv, u.z*mInv, u.w*mInv );
  363. }
  364. inline int operator==( const VectorR4& u, const VectorR4& v )
  365. {
  366. return ( u.x==v.x && u.y==v.y && u.z==v.z && u.w==v.w );
  367. }
  368. inline double operator^ ( const VectorR4& u, const VectorR4& v ) // Dot Product
  369. {
  370. return ( u.x*v.x + u.y*v.y + u.z*v.z + u.w*v.w );
  371. }
  372. inline VectorR4 ArrayProd ( const VectorR4& u, const VectorR4& v )
  373. {
  374. return ( VectorR4( u.x*v.x, u.y*v.y, u.z*v.z, u.w*v.w ) );
  375. }
  376. inline VectorR4& VectorR4::ArrayProd (const VectorR4& v) // Component-wise Product
  377. {
  378. x *= v.x;
  379. y *= v.y;
  380. z *= v.z;
  381. w *= v.w;
  382. return ( *this );
  383. }
  384. inline VectorR4& VectorR4::ArrayProd3 (const VectorR3& v) // Component-wise Product
  385. {
  386. x *= v.x;
  387. y *= v.y;
  388. z *= v.z;
  389. return ( *this );
  390. }
  391. inline VectorR4& VectorR4::AddScaled( const VectorR4& u, double s )
  392. {
  393. x += s*u.x;
  394. y += s*u.y;
  395. z += s*u.z;
  396. w += s*u.w;
  397. return(*this);
  398. }
  399. inline VectorR4& VectorR4::ReNormalize() // Convert near unit back to unit
  400. {
  401. double nSq = NormSq();
  402. register double mFact = 1.0-0.5*(nSq-1.0); // Multiplicative factor
  403. *this *= mFact;
  404. return *this;
  405. }
  406. inline double NormalizeError (const VectorR4& u)
  407. {
  408. register double discrepancy;
  409. discrepancy = u.x*u.x + u.y*u.y + u.z*u.z + u.w*u.w - 1.0;
  410. if ( discrepancy < 0.0 ) {
  411. discrepancy = -discrepancy;
  412. }
  413. return discrepancy;
  414. }
  415. inline VectorR3& VectorR3::SetFromHg(const VectorR4& v) {
  416. double wInv = 1.0/v.w;
  417. x = v.x*wInv;
  418. y = v.y*wInv;
  419. z = v.z*wInv;
  420. return *this;
  421. }
  422. inline double VectorR4::Dist( const VectorR4& u ) const // Distance from u
  423. {
  424. return sqrt( DistSq(u) );
  425. }
  426. inline double VectorR4::DistSq( const VectorR4& u ) const // Distance from u
  427. {
  428. 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) );
  429. }
  430. // *********************************************************
  431. // * Matrix4x4 class - inlined functions *
  432. // * * * * * * * * * * * * * * * * * * * * * * * * * * *****
  433. inline Matrix4x4::Matrix4x4() {}
  434. inline Matrix4x4::Matrix4x4( const VectorR4& u, const VectorR4& v,
  435. const VectorR4& s, const VectorR4& t)
  436. {
  437. m11 = u.x; // Column 1
  438. m21 = u.y;
  439. m31 = u.z;
  440. m41 = u.w;
  441. m12 = v.x; // Column 2
  442. m22 = v.y;
  443. m32 = v.z;
  444. m42 = v.w;
  445. m13 = s.x; // Column 3
  446. m23 = s.y;
  447. m33 = s.z;
  448. m43 = s.w;
  449. m14 = t.x; // Column 4
  450. m24 = t.y;
  451. m34 = t.z;
  452. m44 = t.w;
  453. }
  454. inline Matrix4x4::Matrix4x4( double a11, double a21, double a31, double a41,
  455. double a12, double a22, double a32, double a42,
  456. double a13, double a23, double a33, double a43,
  457. double a14, double a24, double a34, double a44)
  458. // Values specified in column order!!!
  459. {
  460. m11 = a11; // Row 1
  461. m12 = a12;
  462. m13 = a13;
  463. m14 = a14;
  464. m21 = a21; // Row 2
  465. m22 = a22;
  466. m23 = a23;
  467. m24 = a24;
  468. m31 = a31; // Row 3
  469. m32 = a32;
  470. m33 = a33;
  471. m34 = a34;
  472. m41 = a41; // Row 4
  473. m42 = a42;
  474. m43 = a43;
  475. m44 = a44;
  476. }
  477. /*
  478. inline Matrix4x4::Matrix4x4 ( const Matrix4x4& A)
  479. : m11(A.m11), m12(A.m12), m13(A.m13), m14(A.m14),
  480. m21(A.m21), m22(A.m22), m23(A.m23), m24(A.m24),
  481. m31(A.m31), m32(A.m32), m33(A.m33), m34(A.m34),
  482. m41(A.m41), m42(A.m42), m43(A.m43), m44(A.m44) {} */
  483. inline void Matrix4x4::SetIdentity ( )
  484. {
  485. m12 = m13 = m14 =
  486. m21 = m23 = m24 =
  487. m31 = m32 = m34 =
  488. m41 = m42 = m43 = 0.0;
  489. m11 = m22 = m33 = m44 = 1.0;
  490. }
  491. inline void Matrix4x4::Set( const VectorR4& u, const VectorR4& v,
  492. const VectorR4& s, const VectorR4& t )
  493. {
  494. m11 = u.x; // Column 1
  495. m21 = u.y;
  496. m31 = u.z;
  497. m41 = u.w;
  498. m12 = v.x; // Column 2
  499. m22 = v.y;
  500. m32 = v.z;
  501. m42 = v.w;
  502. m13 = s.x; // Column 3
  503. m23 = s.y;
  504. m33 = s.z;
  505. m43 = s.w;
  506. m14 = t.x; // Column 4
  507. m24 = t.y;
  508. m34 = t.z;
  509. m44 = t.w;
  510. }
  511. inline void Matrix4x4::Set( double a11, double a21, double a31, double a41,
  512. double a12, double a22, double a32, double a42,
  513. double a13, double a23, double a33, double a43,
  514. double a14, double a24, double a34, double a44)
  515. // Values specified in column order!!!
  516. {
  517. m11 = a11; // Row 1
  518. m12 = a12;
  519. m13 = a13;
  520. m14 = a14;
  521. m21 = a21; // Row 2
  522. m22 = a22;
  523. m23 = a23;
  524. m24 = a24;
  525. m31 = a31; // Row 3
  526. m32 = a32;
  527. m33 = a33;
  528. m34 = a34;
  529. m41 = a41; // Row 4
  530. m42 = a42;
  531. m43 = a43;
  532. m44 = a44;
  533. }
  534. inline void Matrix4x4::Set ( const Matrix4x4& M ) // Set to the matrix.
  535. {
  536. m11 = M.m11;
  537. m12 = M.m12;
  538. m13 = M.m13;
  539. m14 = M.m14;
  540. m21 = M.m21;
  541. m22 = M.m22;
  542. m23 = M.m23;
  543. m24 = M.m24;
  544. m31 = M.m31;
  545. m32 = M.m32;
  546. m33 = M.m33;
  547. m34 = M.m34;
  548. m41 = M.m41;
  549. m42 = M.m42;
  550. m43 = M.m43;
  551. m44 = M.m44;
  552. }
  553. inline void Matrix4x4::SetZero( )
  554. {
  555. m11 = m12 = m13 = m14 = m21 = m22 = m23 = m24
  556. = m31 = m32 = m33 = m34 = m41 = m42 = m43 = m44 = 0.0;
  557. }
  558. inline void Matrix4x4::SetByRows( const VectorR4& u, const VectorR4& v,
  559. const VectorR4& s, const VectorR4& t )
  560. {
  561. m11 = u.x; // Row 1
  562. m12 = u.y;
  563. m13 = u.z;
  564. m14 = u.w;
  565. m21 = v.x; // Row 2
  566. m22 = v.y;
  567. m23 = v.z;
  568. m24 = v.w;
  569. m31 = s.x; // Row 3
  570. m32 = s.y;
  571. m33 = s.z;
  572. m34 = s.w;
  573. m41 = t.x; // Row 4
  574. m42 = t.y;
  575. m43 = t.z;
  576. m44 = t.w;
  577. }
  578. inline void Matrix4x4::SetByRows( double a11, double a12, double a13, double a14,
  579. double a21, double a22, double a23, double a24,
  580. double a31, double a32, double a33, double a34,
  581. double a41, double a42, double a43, double a44 )
  582. // Values specified in row order!!!
  583. {
  584. m11 = a11; // Row 1
  585. m12 = a12;
  586. m13 = a13;
  587. m14 = a14;
  588. m21 = a21; // Row 2
  589. m22 = a22;
  590. m23 = a23;
  591. m24 = a24;
  592. m31 = a31; // Row 3
  593. m32 = a32;
  594. m33 = a33;
  595. m34 = a34;
  596. m41 = a41; // Row 4
  597. m42 = a42;
  598. m43 = a43;
  599. m44 = a44;
  600. }
  601. inline void Matrix4x4::SetColumn1 ( double x, double y, double z, double w)
  602. {
  603. m11 = x; m21 = y; m31= z; m41 = w;
  604. }
  605. inline void Matrix4x4::SetColumn2 ( double x, double y, double z, double w)
  606. {
  607. m12 = x; m22 = y; m32= z; m42 = w;
  608. }
  609. inline void Matrix4x4::SetColumn3 ( double x, double y, double z, double w)
  610. {
  611. m13 = x; m23 = y; m33= z; m43 = w;
  612. }
  613. inline void Matrix4x4::SetColumn4 ( double x, double y, double z, double w)
  614. {
  615. m14 = x; m24 = y; m34= z; m44 = w;
  616. }
  617. inline void Matrix4x4::SetColumn1 ( const VectorR4& u )
  618. {
  619. m11 = u.x; m21 = u.y; m31 = u.z; m41 = u.w;
  620. }
  621. inline void Matrix4x4::SetColumn2 ( const VectorR4& u )
  622. {
  623. m12 = u.x; m22 = u.y; m32 = u.z; m42 = u.w;
  624. }
  625. inline void Matrix4x4::SetColumn3 ( const VectorR4& u )
  626. {
  627. m13 = u.x; m23 = u.y; m33 = u.z; m43 = u.w;
  628. }
  629. inline void Matrix4x4::SetColumn4 ( const VectorR4& u )
  630. {
  631. m14 = u.x; m24 = u.y; m34 = u.z; m44 = u.w;
  632. }
  633. VectorR4 Matrix4x4::Column1() const
  634. {
  635. return ( VectorR4(m11, m21, m31, m41) );
  636. }
  637. VectorR4 Matrix4x4::Column2() const
  638. {
  639. return ( VectorR4(m12, m22, m32, m42) );
  640. }
  641. VectorR4 Matrix4x4::Column3() const
  642. {
  643. return ( VectorR4(m13, m23, m33, m43) );
  644. }
  645. VectorR4 Matrix4x4::Column4() const
  646. {
  647. return ( VectorR4(m14, m24, m34, m44) );
  648. }
  649. inline void Matrix4x4::SetDiagonal( double x, double y,
  650. double z, double w)
  651. {
  652. m11 = x;
  653. m22 = y;
  654. m33 = z;
  655. m44 = w;
  656. }
  657. inline void Matrix4x4::SetDiagonal( const VectorR4& u )
  658. {
  659. SetDiagonal ( u.x, u.y, u.z, u.w );
  660. }
  661. inline double Matrix4x4::Diagonal( int i )
  662. {
  663. switch (i) {
  664. case 0:
  665. return m11;
  666. case 1:
  667. return m22;
  668. case 2:
  669. return m33;
  670. case 3:
  671. return m44;
  672. default:
  673. assert(0);
  674. return 0.0;
  675. }
  676. }
  677. inline void Matrix4x4::MakeTranspose() // Transposes it.
  678. {
  679. register double temp;
  680. temp = m12;
  681. m12 = m21;
  682. m21=temp;
  683. temp = m13;
  684. m13 = m31;
  685. m31 = temp;
  686. temp = m14;
  687. m14 = m41;
  688. m41 = temp;
  689. temp = m23;
  690. m23 = m32;
  691. m32 = temp;
  692. temp = m24;
  693. m24 = m42;
  694. m42 = temp;
  695. temp = m34;
  696. m34 = m43;
  697. m43 = temp;
  698. }
  699. inline VectorR4 operator* ( const Matrix4x4& A, const VectorR4& u)
  700. {
  701. VectorR4 ret;
  702. ret.x = A.m11*u.x + A.m12*u.y + A.m13*u.z + A.m14*u.w;
  703. ret.y = A.m21*u.x + A.m22*u.y + A.m23*u.z + A.m24*u.w;
  704. ret.z = A.m31*u.x + A.m32*u.y + A.m33*u.z + A.m34*u.w;
  705. ret.w = A.m41*u.x + A.m42*u.y + A.m43*u.z + A.m44*u.w;
  706. return ret;
  707. }
  708. // ******************************************************
  709. // * LinearMapR4 class - inlined functions *
  710. // * * * * * * * * * * * * * * * * * * * * * * * * * * **
  711. inline LinearMapR4::LinearMapR4()
  712. {
  713. SetZero();
  714. return;
  715. }
  716. inline LinearMapR4::LinearMapR4( const VectorR4& u, const VectorR4& v,
  717. const VectorR4& s, const VectorR4& t)
  718. :Matrix4x4 ( u, v, s ,t )
  719. { }
  720. inline LinearMapR4::LinearMapR4(
  721. double a11, double a21, double a31, double a41,
  722. double a12, double a22, double a32, double a42,
  723. double a13, double a23, double a33, double a43,
  724. double a14, double a24, double a34, double a44)
  725. // Values specified in column order!!!
  726. :Matrix4x4 ( a11, a21, a31, a41, a12, a22, a32, a42,
  727. a13, a23, a33, a43, a14, a24, a34, a44 )
  728. { }
  729. inline LinearMapR4::LinearMapR4 ( const Matrix4x4& A )
  730. : Matrix4x4 (A)
  731. {}
  732. inline LinearMapR4& LinearMapR4::operator+= (const LinearMapR4& B)
  733. {
  734. m11 += B.m11;
  735. m12 += B.m12;
  736. m13 += B.m13;
  737. m14 += B.m14;
  738. m21 += B.m21;
  739. m22 += B.m22;
  740. m23 += B.m23;
  741. m24 += B.m24;
  742. m31 += B.m31;
  743. m32 += B.m32;
  744. m33 += B.m33;
  745. m34 += B.m34;
  746. m41 += B.m41;
  747. m42 += B.m42;
  748. m43 += B.m43;
  749. m44 += B.m44;
  750. return ( *this );
  751. }
  752. inline LinearMapR4& LinearMapR4::operator-= (const LinearMapR4& B)
  753. {
  754. m11 -= B.m11;
  755. m12 -= B.m12;
  756. m13 -= B.m13;
  757. m14 -= B.m14;
  758. m21 -= B.m21;
  759. m22 -= B.m22;
  760. m23 -= B.m23;
  761. m24 -= B.m24;
  762. m31 -= B.m31;
  763. m32 -= B.m32;
  764. m33 -= B.m33;
  765. m34 -= B.m34;
  766. m41 -= B.m41;
  767. m42 -= B.m42;
  768. m43 -= B.m43;
  769. m44 -= B.m44;
  770. return( *this );
  771. }
  772. inline LinearMapR4 operator+ (const LinearMapR4& A, const LinearMapR4& B)
  773. {
  774. return( LinearMapR4( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31, A.m41+B.m41,
  775. A.m12+B.m12, A.m22+B.m22, A.m32+B.m32, A.m42+B.m42,
  776. A.m13+B.m13, A.m23+B.m23, A.m33+B.m33, A.m43+B.m43,
  777. A.m14+B.m14, A.m24+B.m24, A.m34+B.m34, A.m44+B.m44) );
  778. }
  779. inline LinearMapR4 operator- (const LinearMapR4& A)
  780. {
  781. return( LinearMapR4( -A.m11, -A.m21, -A.m31, -A.m41,
  782. -A.m12, -A.m22, -A.m32, -A.m42,
  783. -A.m13, -A.m23, -A.m33, -A.m43,
  784. -A.m14, -A.m24, -A.m34, -A.m44 ) );
  785. }
  786. inline LinearMapR4 operator- (const LinearMapR4& A, const LinearMapR4& B)
  787. {
  788. return( LinearMapR4( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31, A.m41-B.m41,
  789. A.m12-B.m12, A.m22-B.m22, A.m32-B.m32, A.m42-B.m42,
  790. A.m13-B.m13, A.m23-B.m23, A.m33-B.m33, A.m43-B.m43,
  791. A.m14-B.m14, A.m24-B.m24, A.m34-B.m34, A.m44-B.m44 ) );
  792. }
  793. inline LinearMapR4& LinearMapR4::operator*= (register double b)
  794. {
  795. m11 *= b;
  796. m12 *= b;
  797. m13 *= b;
  798. m14 *= b;
  799. m21 *= b;
  800. m22 *= b;
  801. m23 *= b;
  802. m24 *= b;
  803. m31 *= b;
  804. m32 *= b;
  805. m33 *= b;
  806. m34 *= b;
  807. m41 *= b;
  808. m42 *= b;
  809. m43 *= b;
  810. m44 *= b;
  811. return ( *this);
  812. }
  813. inline LinearMapR4 operator* ( const LinearMapR4& A, register double b)
  814. {
  815. return( LinearMapR4( A.m11*b, A.m21*b, A.m31*b, A.m41*b,
  816. A.m12*b, A.m22*b, A.m32*b, A.m42*b,
  817. A.m13*b, A.m23*b, A.m33*b, A.m43*b,
  818. A.m14*b, A.m24*b, A.m34*b, A.m44*b) );
  819. }
  820. inline LinearMapR4 operator* ( register double b, const LinearMapR4& A)
  821. {
  822. return( LinearMapR4( A.m11*b, A.m21*b, A.m31*b, A.m41*b,
  823. A.m12*b, A.m22*b, A.m32*b, A.m42*b,
  824. A.m13*b, A.m23*b, A.m33*b, A.m43*b,
  825. A.m14*b, A.m24*b, A.m34*b, A.m44*b ) );
  826. }
  827. inline LinearMapR4 operator/ ( const LinearMapR4& A, double b)
  828. {
  829. register double bInv = 1.0/b;
  830. return ( A*bInv );
  831. }
  832. inline LinearMapR4& LinearMapR4::operator/= (register double b)
  833. {
  834. register double bInv = 1.0/b;
  835. return ( *this *= bInv );
  836. }
  837. inline VectorR4 operator* ( const LinearMapR4& A, const VectorR4& u)
  838. {
  839. return(VectorR4 ( A.m11*u.x + A.m12*u.y + A.m13*u.z + A.m14*u.w,
  840. A.m21*u.x + A.m22*u.y + A.m23*u.z + A.m24*u.w,
  841. A.m31*u.x + A.m32*u.y + A.m33*u.z + A.m34*u.w,
  842. A.m41*u.x + A.m42*u.y + A.m43*u.z + A.m44*u.w ) );
  843. }
  844. inline LinearMapR4 LinearMapR4::Transpose() const // Returns the transpose
  845. {
  846. return (LinearMapR4( m11, m12, m13, m14,
  847. m21, m22, m23, m24,
  848. m31, m32, m33, m34,
  849. m41, m42, m43, m44 ) );
  850. }
  851. inline LinearMapR4& LinearMapR4::operator*= (const Matrix4x4& B) // Matrix product
  852. {
  853. (*this).Matrix4x4::operator*=(B);
  854. return( *this );
  855. }
  856. inline LinearMapR4 operator* ( const LinearMapR4& A, const Matrix4x4& B)
  857. {
  858. LinearMapR4 AA(A);
  859. AA.Matrix4x4::operator*=(B);
  860. return AA;
  861. }
  862. inline LinearMapR4 operator* ( const Matrix4x4& A, const LinearMapR4& B)
  863. {
  864. LinearMapR4 AA(A);
  865. AA.Matrix4x4::operator*=(B);
  866. return AA;
  867. }
  868. // ******************************************************
  869. // * RotationMapR4 class - inlined functions *
  870. // * * * * * * * * * * * * * * * * * * * * * * * * * * **
  871. inline RotationMapR4::RotationMapR4()
  872. {
  873. SetIdentity();
  874. return;
  875. }
  876. inline RotationMapR4::RotationMapR4( const VectorR4& u, const VectorR4& v,
  877. const VectorR4& s, const VectorR4& t)
  878. :Matrix4x4 ( u, v, s ,t )
  879. { }
  880. inline RotationMapR4::RotationMapR4(
  881. double a11, double a21, double a31, double a41,
  882. double a12, double a22, double a32, double a42,
  883. double a13, double a23, double a33, double a43,
  884. double a14, double a24, double a34, double a44)
  885. // Values specified in column order!!!
  886. :Matrix4x4 ( a11, a21, a31, a41, a12, a22, a32, a42,
  887. a13, a23, a33, a43, a14, a24, a34, a44 )
  888. { }
  889. inline RotationMapR4 RotationMapR4::Transpose() const // Returns the transpose
  890. {
  891. return ( RotationMapR4( m11, m12, m13, m14,
  892. m21, m22, m23, m24,
  893. m31, m32, m33, m34,
  894. m41, m42, m43, m44 ) );
  895. }
  896. inline VectorR4 RotationMapR4::Invert(const VectorR4& u) const // Returns solution
  897. {
  898. return (VectorR4( m11*u.x + m21*u.y + m31*u.z + m41*u.w,
  899. m12*u.x + m22*u.y + m32*u.z + m42*u.w,
  900. m13*u.x + m23*u.y + m33*u.z + m43*u.w,
  901. m14*u.x + m24*u.y + m34*u.z + m44*u.w ) );
  902. }
  903. inline RotationMapR4& RotationMapR4::operator*= (const RotationMapR4& B) // Matrix product
  904. {
  905. (*this).Matrix4x4::operator*=(B);
  906. return( *this );
  907. }
  908. inline RotationMapR4 operator* ( const RotationMapR4& A, const RotationMapR4& B)
  909. {
  910. RotationMapR4 AA(A);
  911. AA.Matrix4x4::operator*=(B);
  912. return AA;
  913. }
  914. // ***************************************************************
  915. // * 4-space vector and matrix utilities (inlined functions) *
  916. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  917. inline void TimesTranspose( const VectorR4& u, const VectorR4& v, LinearMapR4& M)
  918. {
  919. M.Set ( v.x*u.x, v.x*u.y, v.x*u.z, v.x*u.w, // Set by columns!
  920. v.y*u.x, v.y*u.y, v.y*u.z, v.y*u.w,
  921. v.z*u.x, v.z*u.y, v.z*u.z, v.z*u.w,
  922. v.w*u.x, v.w*u.y, v.w*u.z, v.w*u.w ) ;
  923. }
  924. // Returns the solid angle between vectors u and v (not necessarily unit vectors)
  925. inline double SolidAngle( const VectorR4& u, const VectorR4& v)
  926. {
  927. double nSqU = u.NormSq();
  928. double nSqV = v.NormSq();
  929. if ( nSqU==0.0 && nSqV==0.0 ) {
  930. return (0.0);
  931. }
  932. else {
  933. return ( SolidAngleUnit( u/sqrt(nSqU), v/sqrt(nSqV) ) );
  934. }
  935. }
  936. inline double SolidAngleUnit( const VectorR4 u, const VectorR4 v )
  937. {
  938. return ( atan2 ( ProjectPerpUnit(v,u).Norm(), u^v ) );
  939. }
  940. #endif // LINEAR_R4_H