vecmath.h
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:27k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // vecmath.h
  2. //
  3. // Copyright (C) 2000, Chris Laurel <claurel@shatters.net>
  4. //
  5. // Basic templatized vector and matrix math library.
  6. //
  7. // This program is free software; you can redistribute it and/or
  8. // modify it under the terms of the GNU General Public License
  9. // as published by the Free Software Foundation; either version 2
  10. // of the License, or (at your option) any later version.
  11. #ifndef _VECMATH_H_
  12. #define _VECMATH_H_
  13. #include <cmath>
  14. template<class T> class Point3;
  15. template<class T> class Vector3
  16. {
  17. public:
  18.     inline Vector3();
  19.     inline Vector3(const Vector3<T>&);
  20.     inline Vector3(T, T, T);
  21.     inline Vector3(T*);
  22.     inline T& operator[](int) const;
  23.     inline Vector3& operator+=(const Vector3<T>&);
  24.     inline Vector3& operator-=(const Vector3<T>&);
  25.     inline Vector3& operator*=(T);
  26.     inline Vector3 operator-() const;
  27.     inline Vector3 operator+() const;
  28.     inline T length() const;
  29.     inline T lengthSquared() const;
  30.     inline void normalize();
  31.     T x, y, z;
  32. };
  33. template<class T> class Point3
  34. {
  35. public:
  36.     inline Point3();
  37.     inline Point3(const Point3&);
  38.     inline Point3(T, T, T);
  39.     inline Point3(T*);
  40.     inline T& operator[](int) const;
  41.     inline Point3& operator+=(const Vector3<T>&);
  42.     inline Point3& operator-=(const Vector3<T>&);
  43.     inline Point3& operator*=(T);
  44.     inline T distanceTo(const Point3&) const;
  45.     inline T distanceToSquared(const Point3&) const;
  46.     inline T distanceFromOrigin() const;
  47.     inline T distanceFromOriginSquared() const;
  48.     T x, y, z;
  49. };
  50. template<class T> class Point2;
  51. template<class T> class Vector2
  52. {
  53. public:
  54.     inline Vector2();
  55.     inline Vector2(T, T);
  56.     T x, y;
  57. };
  58. template<class T> class Point2
  59. {
  60. public:
  61.     inline Point2();
  62.     inline Point2(T, T);
  63.     T x, y;
  64. };
  65. template<class T> class Vector4
  66. {
  67.  public:
  68.     inline Vector4();
  69.     inline Vector4(T, T, T, T);
  70.     inline T& operator[](int) const;
  71.     inline Vector4& operator+=(const Vector4&);
  72.     inline Vector4& operator-=(const Vector4&);
  73.     inline Vector4& operator*=(T);
  74.     inline Vector4 operator-() const;
  75.     inline Vector4 operator+() const;
  76.     T x, y, z, w;
  77. };
  78. template<class T> class Matrix4
  79. {
  80.  public:
  81.     Matrix4();
  82.     Matrix4(const Vector4<T>&, const Vector4<T>&,
  83.             const Vector4<T>&, const Vector4<T>&);
  84.     Matrix4(const Matrix4<T>& m);
  85.     inline const Vector4<T>& operator[](int) const;
  86.     inline Vector4<T> row(int) const;
  87.     inline Vector4<T> column(int) const;
  88.     static Matrix4<T> identity();
  89.     static Matrix4<T> translation(const Point3<T>&);
  90.     static Matrix4<T> translation(const Vector3<T>&);
  91.     static Matrix4<T> rotation(const Vector3<T>&, T);
  92.     static Matrix4<T> xrotation(T);
  93.     static Matrix4<T> yrotation(T);
  94.     static Matrix4<T> zrotation(T);
  95.     static Matrix4<T> scaling(const Vector3<T>&);
  96.     static Matrix4<T> scaling(T);
  97.     void translate(const Point3<T>&);
  98.     Matrix4<T> transpose() const;
  99.     Matrix4<T> inverse() const;
  100.     Vector4<T> r[4];
  101. };
  102. template<class T> class Matrix3
  103. {
  104.  public:
  105.     Matrix3();
  106.     Matrix3(const Vector3<T>&, const Vector3<T>&, const Vector3<T>&);
  107.     template<class U> Matrix3(const Matrix3<U>&);
  108.     static Matrix3<T> xrotation(T);
  109.     static Matrix3<T> yrotation(T);
  110.     static Matrix3<T> zrotation(T);
  111.     static Matrix3<T> scaling(const Vector3<T>&);
  112.     static Matrix3<T> scaling(T);
  113.     inline const Vector3<T>& operator[](int) const;
  114.     inline Vector3<T> row(int) const;
  115.     inline Vector3<T> column(int) const;
  116.     inline Matrix3& operator*=(T);
  117.     static Matrix3<T> identity();
  118.     Matrix3<T> transpose() const;
  119.     Matrix3<T> inverse() const;
  120.     T determinant() const;
  121.     //    template<class U> operator Matrix3<U>() const;
  122.     Vector3<T> r[3];
  123. };
  124. typedef Vector3<float>   Vec3f;
  125. typedef Vector3<double>  Vec3d;
  126. typedef Point3<float>    Point3f;
  127. typedef Point3<double>   Point3d;
  128. typedef Vector2<float>   Vec2f;
  129. typedef Point2<float>    Point2f;
  130. typedef Vector4<float>   Vec4f;
  131. typedef Vector4<double>  Vec4d;
  132. typedef Matrix4<float>   Mat4f;
  133. typedef Matrix4<double>  Mat4d;
  134. typedef Matrix3<float>   Mat3f;
  135. typedef Matrix3<double>  Mat3d;
  136. //**** Vector3 constructors
  137. template<class T> Vector3<T>::Vector3() : x(0), y(0), z(0)
  138. {
  139. }
  140. template<class T> Vector3<T>::Vector3(const Vector3<T>& v) :
  141.     x(v.x), y(v.y), z(v.z)
  142. {
  143. }
  144. template<class T> Vector3<T>::Vector3(T _x, T _y, T _z) : x(_x), y(_y), z(_z)
  145. {
  146. }
  147. template<class T> Vector3<T>::Vector3(T* v) : x(v[0]), y(v[1]), z(v[2])
  148. {
  149. }
  150. //**** Vector3 operators
  151. template<class T> T& Vector3<T>::operator[](int n) const
  152. {
  153.     // Not portable--I'll write a new version when I try to compile on a
  154.     // platform where it bombs.
  155.     return ((T*) this)[n];
  156. }
  157. template<class T> Vector3<T>& Vector3<T>::operator+=(const Vector3<T>& a)
  158. {
  159.     x += a.x; y += a.y; z += a.z;
  160.     return *this;
  161. }
  162. template<class T> Vector3<T>& Vector3<T>::operator-=(const Vector3<T>& a)
  163. {
  164.     x -= a.x; y -= a.y; z -= a.z;
  165.     return *this;
  166. }
  167. template<class T> Vector3<T>& Vector3<T>::operator*=(T s)
  168. {
  169.     x *= s; y *= s; z *= s;
  170.     return *this;
  171. }
  172. template<class T> Vector3<T> Vector3<T>::operator-() const
  173. {
  174.     return Vector3<T>(-x, -y, -z);
  175. }
  176. template<class T> Vector3<T> Vector3<T>::operator+() const
  177. {
  178.     return *this;
  179. }
  180. template<class T> Vector3<T> operator+(const Vector3<T>& a, const Vector3<T>& b)
  181. {
  182.     return Vector3<T>(a.x + b.x, a.y + b.y, a.z + b.z);
  183. }
  184. template<class T> Vector3<T> operator-(const Vector3<T>& a, const Vector3<T>& b)
  185. {
  186.     return Vector3<T>(a.x - b.x, a.y - b.y, a.z - b.z);
  187. }
  188. template<class T> Vector3<T> operator*(T s, const Vector3<T>& v)
  189. {
  190.     return Vector3<T>(s * v.x, s * v.y, s * v.z);
  191. }
  192. template<class T> Vector3<T> operator*(const Vector3<T>& v, T s)
  193. {
  194.     return Vector3<T>(s * v.x, s * v.y, s * v.z);
  195. }
  196. // dot product
  197. template<class T> T operator*(const Vector3<T>& a, const Vector3<T>& b)
  198. {
  199.     return a.x * b.x + a.y * b.y + a.z * b.z;
  200. }
  201. // cross product
  202. template<class T> Vector3<T> operator^(const Vector3<T>& a, const Vector3<T>& b)
  203. {
  204.     return Vector3<T>(a.y * b.z - a.z * b.y,
  205.                       a.z * b.x - a.x * b.z,
  206.                       a.x * b.y - a.y * b.x);
  207. }
  208. template<class T> bool operator==(const Vector3<T>& a, const Vector3<T>& b)
  209. {
  210.     return a.x == b.x && a.y == b.y && a.z == b.z;
  211. }
  212. template<class T> bool operator!=(const Vector3<T>& a, const Vector3<T>& b)
  213. {
  214.     return a.x != b.x || a.y != b.y || a.z != b.z;
  215. }
  216. template<class T> Vector3<T> operator/(const Vector3<T>& v, T s)
  217. {
  218.     T is = 1 / s;
  219.     return Vector3<T>(is * v.x, is * v.y, is * v.z);
  220. }
  221. template<class T> T dot(const Vector3<T>& a, const Vector3<T>& b)
  222. {
  223.     return a.x * b.x + a.y * b.y + a.z * b.z;
  224. }
  225. template<class T> Vector3<T> cross(const Vector3<T>& a, const Vector3<T>& b)
  226. {
  227.     return Vector3<T>(a.y * b.z - a.z * b.y,
  228.                       a.z * b.x - a.x * b.z,
  229.                       a.x * b.y - a.y * b.x);
  230. }
  231. template<class T> T Vector3<T>::length() const
  232. {
  233.     return (T) sqrt(x * x + y * y + z * z);
  234. }
  235. template<class T> T Vector3<T>::lengthSquared() const
  236. {
  237.     return x * x + y * y + z * z;
  238. }
  239. template<class T> void Vector3<T>::normalize()
  240. {
  241.     T s = 1 / (T) sqrt(x * x + y * y + z * z);
  242.     x *= s;
  243.     y *= s;
  244.     z *= s;
  245. }
  246. //**** Point3 constructors
  247. template<class T> Point3<T>::Point3() : x(0), y(0), z(0)
  248. {
  249. }
  250. template<class T> Point3<T>::Point3(const Point3<T>& p) :
  251.     x(p.x), y(p.y), z(p.z)
  252. {
  253. }
  254. template<class T> Point3<T>::Point3(T _x, T _y, T _z) : x(_x), y(_y), z(_z)
  255. {
  256. }
  257. template<class T> Point3<T>::Point3(T* p) : x(p[0]), y(p[1]), z(p[2])
  258. {
  259. }
  260. //**** Point3 operators
  261. template<class T> T& Point3<T>::operator[](int n) const
  262. {
  263.     // Not portable--I'll write a new version when I try to compile on a
  264.     // platform where it bombs.
  265.     return ((T*) this)[n];
  266. }
  267. template<class T> Vector3<T> operator-(const Point3<T>& a, const Point3<T>& b)
  268. {
  269.     return Vector3<T>(a.x - b.x, a.y - b.y, a.z - b.z);
  270. }
  271. template<class T> Point3<T>& Point3<T>::operator+=(const Vector3<T>& v)
  272. {
  273.     x += v.x; y += v.y; z += v.z;
  274.     return *this;
  275. }
  276. template<class T> Point3<T>& Point3<T>::operator-=(const Vector3<T>& v)
  277. {
  278.     x -= v.x; y -= v.y; z -= v.z;
  279.     return *this;
  280. }
  281. template<class T> Point3<T>& Point3<T>::operator*=(T s)
  282. {
  283.     x *= s; y *= s; z *= s;
  284.     return *this;
  285. }
  286. template<class T> bool operator==(const Point3<T>& a, const Point3<T>& b)
  287. {
  288.     return a.x == b.x && a.y == b.y && a.z == b.z;
  289. }
  290. template<class T> bool operator!=(const Point3<T>& a, const Point3<T>& b)
  291. {
  292.     return a.x != b.x || a.y != b.y || a.z != b.z;
  293. }
  294. template<class T> Point3<T> operator+(const Point3<T>& p, const Vector3<T>& v)
  295. {
  296.     return Point3<T>(p.x + v.x, p.y + v.y, p.z + v.z);
  297. }
  298. template<class T> Point3<T> operator-(const Point3<T>& p, const Vector3<T>& v)
  299. {
  300.     return Point3<T>(p.x - v.x, p.y - v.y, p.z - v.z);
  301. }
  302. // Naughty naughty . . .  remove these since they aren't proper
  303. // point methods--changing the implicit homogenous coordinate isn't
  304. // allowed.
  305. template<class T> Point3<T> operator*(const Point3<T>& p, T s)
  306. {
  307.     return Point3<T>(p.x * s, p.y * s, p.z * s);
  308. }
  309. template<class T> Point3<T> operator*(T s, const Point3<T>& p)
  310. {
  311.     return Point3<T>(p.x * s, p.y * s, p.z * s);
  312. }
  313. //**** Point3 methods
  314. template<class T> T Point3<T>::distanceTo(const Point3& p) const
  315. {
  316.     return (T) sqrt((p.x - x) * (p.x - x) +
  317.                     (p.y - y) * (p.y - y) +
  318.                     (p.z - z) * (p.z - z));
  319. }
  320. template<class T> T Point3<T>::distanceToSquared(const Point3& p) const
  321. {
  322.     return ((p.x - x) * (p.x - x) +
  323.             (p.y - y) * (p.y - y) +
  324.             (p.z - z) * (p.z - z));
  325. }
  326. template<class T> T Point3<T>::distanceFromOrigin() const
  327. {
  328.     return (T) sqrt(x * x + y * y + z * z);
  329. }
  330. template<class T> T Point3<T>::distanceFromOriginSquared() const
  331. {
  332.     return x * x + y * y + z * z;
  333. }
  334. //**** Vector2 constructors
  335. template<class T> Vector2<T>::Vector2() : x(0), y(0)
  336. {
  337. }
  338. template<class T> Vector2<T>::Vector2(T _x, T _y) : x(_x), y(_y)
  339. {
  340. }
  341. //**** Vector2 operators
  342. template<class T> bool operator==(const Vector2<T>& a, const Vector2<T>& b)
  343. {
  344.     return a.x == b.x && a.y == b.y;
  345. }
  346. template<class T> bool operator!=(const Vector2<T>& a, const Vector2<T>& b)
  347. {
  348.     return a.x != b.x || a.y != b.y;
  349. }
  350. //**** Point2 constructors
  351. template<class T> Point2<T>::Point2() : x(0), y(0)
  352. {
  353. }
  354. template<class T> Point2<T>::Point2(T _x, T _y) : x(_x), y(_y)
  355. {
  356. }
  357. //**** Point2 operators
  358. template<class T> bool operator==(const Point2<T>& a, const Point2<T>& b)
  359. {
  360.     return a.x == b.x && a.y == b.y;
  361. }
  362. template<class T> bool operator!=(const Point2<T>& a, const Point2<T>& b)
  363. {
  364.     return a.x != b.x || a.y != b.y;
  365. }
  366. //**** Vector4 constructors
  367. template<class T> Vector4<T>::Vector4() : x(0), y(0), z(0), w(0)
  368. {
  369. }
  370. template<class T> Vector4<T>::Vector4(T _x, T _y, T _z, T _w) :
  371.     x(_x), y(_y), z(_z), w(_w)
  372. {
  373. }
  374. //**** Vector4 operators
  375. template<class T> T& Vector4<T>::operator[](int n) const
  376. {
  377.     // Not portable--I'll write a new version when I try to compile on a
  378.     // platform where it bombs.
  379.     return ((T*) this)[n];
  380. }
  381. template<class T> bool operator==(const Vector4<T>& a, const Vector4<T>& b)
  382. {
  383.     return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w;
  384. }
  385. template<class T> bool operator!=(const Vector4<T>& a, const Vector4<T>& b)
  386. {
  387.     return a.x != b.x || a.y != b.y || a.z != b.z || a.w != b.w;
  388. }
  389. template<class T> Vector4<T>& Vector4<T>::operator+=(const Vector4<T>& a)
  390. {
  391.     x += a.x; y += a.y; z += a.z; w += a.w;
  392.     return *this;
  393. }
  394. template<class T> Vector4<T>& Vector4<T>::operator-=(const Vector4<T>& a)
  395. {
  396.     x -= a.x; y -= a.y; z -= a.z; w -= a.w;
  397.     return *this;
  398. }
  399. template<class T> Vector4<T>& Vector4<T>::operator*=(T s)
  400. {
  401.     x *= s; y *= s; z *= s; w *= s;
  402.     return *this;
  403. }
  404. template<class T> Vector4<T> Vector4<T>::operator-() const
  405. {
  406.     return Vector4<T>(-x, -y, -z, -w);
  407. }
  408. template<class T> Vector4<T> Vector4<T>::operator+() const
  409. {
  410.     return *this;
  411. }
  412. template<class T> Vector4<T> operator+(const Vector4<T>& a, const Vector4<T>& b)
  413. {
  414.     return Vector4<T>(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
  415. }
  416. template<class T> Vector4<T> operator-(const Vector4<T>& a, const Vector4<T>& b)
  417. {
  418.     return Vector4<T>(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
  419. }
  420. template<class T> Vector4<T> operator*(T s, const Vector4<T>& v)
  421. {
  422.     return Vector4<T>(s * v.x, s * v.y, s * v.z, s * v.w);
  423. }
  424. template<class T> Vector4<T> operator*(const Vector4<T>& v, T s)
  425. {
  426.     return Vector4<T>(s * v.x, s * v.y, s * v.z, s * v.w);
  427. }
  428. // dot product
  429. template<class T> T operator*(const Vector4<T>& a, const Vector4<T>& b)
  430. {
  431.     return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
  432. }
  433. template<class T> T dot(const Vector4<T>& a, const Vector4<T>& b)
  434. {
  435.     return a * b;
  436. }
  437. //**** Matrix3 constructors
  438. template<class T> Matrix3<T>::Matrix3()
  439. {
  440.     r[0] = Vector3<T>(0, 0, 0);
  441.     r[1] = Vector3<T>(0, 0, 0);
  442.     r[2] = Vector3<T>(0, 0, 0);
  443. }
  444. template<class T> Matrix3<T>::Matrix3(const Vector3<T>& r0,
  445.                                       const Vector3<T>& r1,
  446.                                       const Vector3<T>& r2)
  447. {
  448.     r[0] = r0;
  449.     r[1] = r1;
  450.     r[2] = r2;
  451. }
  452. #if 0
  453. template<class T, class U> Matrix3<T>::Matrix3(const Matrix3<U>& m)
  454. {
  455. #if 0
  456.     r[0] = m.r[0];
  457.     r[1] = m.r[1];
  458.     r[2] = m.r[2];
  459. #endif
  460.     r[0].x = m.r[0].x; r[0].y = m.r[0].y; r[0].z = m.r[0].z;
  461.     r[1].x = m.r[1].x; r[1].y = m.r[1].y; r[1].z = m.r[1].z;
  462.     r[2].x = m.r[2].x; r[2].y = m.r[2].y; r[2].z = m.r[2].z;
  463. }
  464. #endif
  465. //**** Matrix3 operators
  466. template<class T> const Vector3<T>& Matrix3<T>::operator[](int n) const
  467. {
  468.     //    return const_cast<Vector3<T>&>(r[n]);
  469.     return r[n];
  470. }
  471. template<class T> Vector3<T> Matrix3<T>::row(int n) const
  472. {
  473.     return r[n];
  474. }
  475. template<class T> Vector3<T> Matrix3<T>::column(int n) const
  476. {
  477.     return Vector3<T>(r[0][n], r[1][n], r[2][n]);
  478. }
  479. template<class T> Matrix3<T>& Matrix3<T>::operator*=(T s)
  480. {
  481.     r[0] *= s;
  482.     r[1] *= s;
  483.     r[2] *= s;
  484.     return *this;
  485. }
  486. // pre-multiply column vector by a 3x3 matrix
  487. template<class T> Vector3<T> operator*(const Matrix3<T>& m, const Vector3<T>& v)
  488. {
  489.     return Vector3<T>(m.r[0].x * v.x + m.r[0].y * v.y + m.r[0].z * v.z,
  490.       m.r[1].x * v.x + m.r[1].y * v.y + m.r[1].z * v.z,
  491.       m.r[2].x * v.x + m.r[2].y * v.y + m.r[2].z * v.z);
  492. }
  493. // post-multiply row vector by a 3x3 matrix
  494. template<class T> Vector3<T> operator*(const Vector3<T>& v, const Matrix3<T>& m)
  495. {
  496.     return Vector3<T>(m.r[0].x * v.x + m.r[1].x * v.y + m.r[2].x * v.z,
  497.                       m.r[0].y * v.x + m.r[1].y * v.y + m.r[2].y * v.z,
  498.                       m.r[0].z * v.x + m.r[1].z * v.y + m.r[2].z * v.z);
  499. }
  500. // pre-multiply column point by a 3x3 matrix
  501. template<class T> Point3<T> operator*(const Matrix3<T>& m, const Point3<T>& p)
  502. {
  503.     return Point3<T>(m.r[0].x * p.x + m.r[0].y * p.y + m.r[0].z * p.z,
  504.                      m.r[1].x * p.x + m.r[1].y * p.y + m.r[1].z * p.z,
  505.                      m.r[2].x * p.x + m.r[2].y * p.y + m.r[2].z * p.z);
  506. }
  507. // post-multiply row point by a 3x3 matrix
  508. template<class T> Point3<T> operator*(const Point3<T>& p, const Matrix3<T>& m)
  509. {
  510.     return Point3<T>(m.r[0].x * p.x + m.r[1].x * p.y + m.r[2].x * p.z,
  511.      m.r[0].y * p.x + m.r[1].y * p.y + m.r[2].y * p.z,
  512.      m.r[0].z * p.x + m.r[1].z * p.y + m.r[2].z * p.z);
  513. }
  514. template<class T> Matrix3<T> operator*(const Matrix3<T>& a,
  515.                                        const Matrix3<T>& b)
  516. {
  517. #define MATMUL(R, C) (a[R].x * b[0].C + a[R].y * b[1].C + a[R].z * b[2].C)
  518.     return Matrix3<T>(Vector3<T>(MATMUL(0, x), MATMUL(0, y), MATMUL(0, z)),
  519.                       Vector3<T>(MATMUL(1, x), MATMUL(1, y), MATMUL(1, z)),
  520.                       Vector3<T>(MATMUL(2, x), MATMUL(2, y), MATMUL(2, z)));
  521. #undef MATMUL
  522. }
  523. template<class T> Matrix3<T> operator+(const Matrix3<T>& a,
  524.                                        const Matrix3<T>& b)
  525. {
  526.     return Matrix3<T>(a.r[0] + b.r[0],
  527.                       a.r[1] + b.r[1],
  528.                       a.r[2] + b.r[2]);
  529. }
  530. template<class T> Matrix3<T> Matrix3<T>::identity()
  531. {
  532.     return Matrix3<T>(Vector3<T>(1, 0, 0),
  533.                       Vector3<T>(0, 1, 0),
  534.                       Vector3<T>(0, 0, 1));
  535. }
  536. template<class T> Matrix3<T> Matrix3<T>::transpose() const
  537. {
  538.     return Matrix3<T>(Vector3<T>(r[0].x, r[1].x, r[2].x),
  539.                       Vector3<T>(r[0].y, r[1].y, r[2].y),
  540.                       Vector3<T>(r[0].z, r[1].z, r[2].z));
  541. }
  542. template<class T> T det2x2(T a, T b, T c, T d)
  543. {
  544.     return a * d - b * c;
  545. }
  546. template<class T> T Matrix3<T>::determinant() const
  547. {
  548.     return (r[0].x * r[1].y * r[2].z +
  549.             r[0].y * r[1].z * r[2].x +
  550.             r[0].z * r[1].x * r[2].y -
  551.             r[0].z * r[1].y * r[2].x -
  552.             r[0].x * r[1].z * r[2].y -
  553.             r[0].y * r[1].x * r[2].z);
  554. }
  555. template<class T> Matrix3<T> Matrix3<T>::inverse() const
  556. {
  557.     Matrix3<T> adjoint;
  558.     // Just use Cramer's rule for now . . .
  559.     adjoint.r[0].x =  det2x2(r[1].y, r[1].z, r[2].y, r[2].z);
  560.     adjoint.r[0].y = -det2x2(r[1].x, r[1].z, r[2].x, r[2].z);
  561.     adjoint.r[0].z =  det2x2(r[1].x, r[1].y, r[2].x, r[2].y);
  562.     adjoint.r[1].x = -det2x2(r[0].y, r[0].z, r[2].y, r[2].z);
  563.     adjoint.r[1].y =  det2x2(r[0].x, r[0].z, r[2].x, r[2].z);
  564.     adjoint.r[1].z = -det2x2(r[0].x, r[0].y, r[2].x, r[2].y);
  565.     adjoint.r[2].x =  det2x2(r[0].y, r[0].z, r[1].y, r[1].z);
  566.     adjoint.r[2].y = -det2x2(r[0].x, r[0].z, r[1].x, r[1].z);
  567.     adjoint.r[2].z =  det2x2(r[0].x, r[0].y, r[1].x, r[1].y);
  568.     adjoint *= 1 / determinant();
  569.     return adjoint;
  570. }
  571. template<class T> Matrix3<T> Matrix3<T>::xrotation(T angle)
  572. {
  573.     T c = (T) cos(angle);
  574.     T s = (T) sin(angle);
  575.     return Matrix3<T>(Vector3<T>(1, 0, 0),
  576.                       Vector3<T>(0, c, -s),
  577.                       Vector3<T>(0, s, c));
  578. }
  579. template<class T> Matrix3<T> Matrix3<T>::yrotation(T angle)
  580. {
  581.     T c = (T) cos(angle);
  582.     T s = (T) sin(angle);
  583.     return Matrix3<T>(Vector3<T>(c, 0, s),
  584.                       Vector3<T>(0, 1, 0),
  585.                       Vector3<T>(-s, 0, c));
  586. }
  587. template<class T> Matrix3<T> Matrix3<T>::zrotation(T angle)
  588. {
  589.     T c = (T) cos(angle);
  590.     T s = (T) sin(angle);
  591.     return Matrix3<T>(Vector3<T>(c, -s, 0),
  592.                       Vector3<T>(s, c, 0),
  593.                       Vector3<T>(0, 0, 1));
  594. }
  595. template<class T> Matrix3<T> Matrix3<T>::scaling(const Vector3<T>& scale)
  596. {
  597.     return Matrix3<T>(Vector3<T>(scale.x, 0, 0),
  598.                       Vector3<T>(0, scale.y, 0),
  599.                       Vector3<T>(0, 0, scale.z));
  600. }
  601. template<class T> Matrix3<T> Matrix3<T>::scaling(T scale)
  602. {
  603.     return scaling(Vector3<T>(scale, scale, scale));
  604. }
  605. /***********************************************
  606.  **
  607.  **  Matrix4 methods
  608.  **
  609.  ***********************************************/
  610. template<class T> Matrix4<T>::Matrix4()
  611. {
  612.     r[0] = Vector4<T>(0, 0, 0, 0);
  613.     r[1] = Vector4<T>(0, 0, 0, 0);
  614.     r[2] = Vector4<T>(0, 0, 0, 0);
  615.     r[3] = Vector4<T>(0, 0, 0, 0);
  616. }
  617. template<class T> Matrix4<T>::Matrix4(const Vector4<T>& v0,
  618.                                       const Vector4<T>& v1,
  619.                                       const Vector4<T>& v2,
  620.                                       const Vector4<T>& v3)
  621. {
  622.     r[0] = v0;
  623.     r[1] = v1;
  624.     r[2] = v2;
  625.     r[3] = v3;
  626. }
  627. template<class T> Matrix4<T>::Matrix4(const Matrix4<T>& m)
  628. {
  629.     r[0] = m.r[0];
  630.     r[1] = m.r[1];
  631.     r[2] = m.r[2];
  632.     r[3] = m.r[3];
  633. }
  634. template<class T> const Vector4<T>& Matrix4<T>::operator[](int n) const
  635. {
  636.     return r[n];
  637.     //    return const_cast<Vector4<T>&>(r[n]);
  638. }
  639. template<class T> Vector4<T> Matrix4<T>::row(int n) const
  640. {
  641.     return r[n];
  642. }
  643. template<class T> Vector4<T> Matrix4<T>::column(int n) const
  644. {
  645.     return Vector4<T>(r[0][n], r[1][n], r[2][n], r[3][n]);
  646. }
  647. template<class T> Matrix4<T> Matrix4<T>::identity()
  648. {
  649.     return Matrix4<T>(Vector4<T>(1, 0, 0, 0),
  650.                       Vector4<T>(0, 1, 0, 0),
  651.                       Vector4<T>(0, 0, 1, 0),
  652.                       Vector4<T>(0, 0, 0, 1));
  653. }
  654. template<class T> Matrix4<T> Matrix4<T>::translation(const Point3<T>& p)
  655. {
  656.     return Matrix4<T>(Vector4<T>(1, 0, 0, 0),
  657.                       Vector4<T>(0, 1, 0, 0),
  658.                       Vector4<T>(0, 0, 1, 0),
  659.                       Vector4<T>(p.x, p.y, p.z, 1));
  660. }
  661. template<class T> Matrix4<T> Matrix4<T>::translation(const Vector3<T>& v)
  662. {
  663.     return Matrix4<T>(Vector4<T>(1, 0, 0, 0),
  664.                       Vector4<T>(0, 1, 0, 0),
  665.                       Vector4<T>(0, 0, 1, 0),
  666.                       Vector4<T>(v.x, v.y, v.z, 1));
  667. }
  668. template<class T> void Matrix4<T>::translate(const Point3<T>& p)
  669. {
  670.     r[3].x += p.x;
  671.     r[3].y += p.y;
  672.     r[3].z += p.z;
  673. }
  674. template<class T> Matrix4<T> Matrix4<T>::rotation(const Vector3<T>& axis,
  675.                                                   T angle)
  676. {
  677.     T c = (T) cos(angle);
  678.     T s = (T) sin(angle);
  679.     T t = 1 - c;
  680.     return Matrix4<T>(Vector4<T>(t * axis.x * axis.x + c,
  681.                                  t * axis.x * axis.y - s * axis.z,
  682.                                  t * axis.x * axis.z + s * axis.y,
  683.                                  0),
  684.                       Vector4<T>(t * axis.x * axis.y + s * axis.z,
  685.                                  t * axis.y * axis.y + c,
  686.                                  t * axis.y * axis.z - s * axis.x,
  687.                                  0),
  688.                       Vector4<T>(t * axis.x * axis.z - s * axis.y,
  689.                                  t * axis.y * axis.z + s * axis.x,
  690.                                  t * axis.z * axis.z + c,
  691.                                  0),
  692.                       Vector4<T>(0, 0, 0, 1));
  693. }
  694. template<class T> Matrix4<T> Matrix4<T>::xrotation(T angle)
  695. {
  696.     T c = (T) cos(angle);
  697.     T s = (T) sin(angle);
  698.     return Matrix4<T>(Vector4<T>(1, 0, 0, 0),
  699.                       Vector4<T>(0, c, -s, 0),
  700.                       Vector4<T>(0, s, c, 0),
  701.                       Vector4<T>(0, 0, 0, 1));
  702. }
  703. template<class T> Matrix4<T> Matrix4<T>::yrotation(T angle)
  704. {
  705.     T c = (T) cos(angle);
  706.     T s = (T) sin(angle);
  707.     return Matrix4<T>(Vector4<T>(c, 0, s, 0),
  708.                       Vector4<T>(0, 1, 0, 0),
  709.                       Vector4<T>(-s, 0, c, 0),
  710.                       Vector4<T>(0, 0, 0, 1));
  711. }
  712. template<class T> Matrix4<T> Matrix4<T>::zrotation(T angle)
  713. {
  714.     T c = (T) cos(angle);
  715.     T s = (T) sin(angle);
  716.     return Matrix4<T>(Vector4<T>(c, -s, 0, 0),
  717.                       Vector4<T>(s, c, 0, 0),
  718.                       Vector4<T>(0, 0, 1, 0),
  719.                       Vector4<T>(0, 0, 0, 1));
  720. }
  721. template<class T> Matrix4<T> Matrix4<T>::scaling(const Vector3<T>& scale)
  722. {
  723.     return Matrix4<T>(Vector4<T>(scale.x, 0, 0, 0),
  724.                       Vector4<T>(0, scale.y, 0, 0),
  725.                       Vector4<T>(0, 0, scale.z, 0),
  726.                       Vector4<T>(0, 0, 0, 1));
  727. }
  728. template<class T> Matrix4<T> Matrix4<T>::scaling(T scale)
  729. {
  730.     return scaling(Vector3<T>(scale, scale, scale));
  731. }
  732. // multiply column vector by a 4x4 matrix
  733. template<class T> Vector3<T> operator*(const Matrix4<T>& m, const Vector3<T>& v)
  734. {
  735.     return Vector3<T>(m.r[0].x * v.x + m.r[0].y * v.y + m.r[0].z * v.z,
  736.       m.r[1].x * v.x + m.r[1].y * v.y + m.r[1].z * v.z,
  737.       m.r[2].x * v.x + m.r[2].y * v.y + m.r[2].z * v.z);
  738. }
  739. // multiply row vector by a 4x4 matrix
  740. template<class T> Vector3<T> operator*(const Vector3<T>& v, const Matrix4<T>& m)
  741. {
  742.     return Vector3<T>(m.r[0].x * v.x + m.r[1].x * v.y + m.r[2].x * v.z,
  743.                       m.r[0].y * v.x + m.r[1].y * v.y + m.r[2].y * v.z,
  744.                       m.r[0].z * v.x + m.r[1].z * v.y + m.r[2].z * v.z);
  745. }
  746. // multiply column point by a 4x4 matrix; no projection is performed
  747. template<class T> Point3<T> operator*(const Matrix4<T>& m, const Point3<T>& p)
  748. {
  749.     return Point3<T>(m.r[0].x * p.x + m.r[0].y * p.y + m.r[0].z * p.z + m.r[0].w,
  750.                      m.r[1].x * p.x + m.r[1].y * p.y + m.r[1].z * p.z + m.r[1].w,
  751.                      m.r[2].x * p.x + m.r[2].y * p.y + m.r[2].z * p.z + m.r[2].w);
  752. }
  753. // multiply row point by a 4x4 matrix; no projection is performed
  754. template<class T> Point3<T> operator*(const Point3<T>& p, const Matrix4<T>& m)
  755. {
  756.     return Point3<T>(m.r[0].x * p.x + m.r[1].x * p.y + m.r[2].x * p.z + m.r[3].x,
  757.      m.r[0].y * p.x + m.r[1].y * p.y + m.r[2].y * p.z + m.r[3].y,
  758.      m.r[0].z * p.x + m.r[1].z * p.y + m.r[2].z * p.z + m.r[3].z);
  759. }
  760. // multiply column vector by a 4x4 matrix
  761. template<class T> Vector4<T> operator*(const Matrix4<T>& m, const Vector4<T>& v)
  762. {
  763.     return Vector4<T>(m.r[0].x * v.x + m.r[0].y * v.y + m.r[0].z * v.z + m.r[0].w * v.w,
  764.       m.r[1].x * v.x + m.r[1].y * v.y + m.r[1].z * v.z + m.r[1].w * v.w,
  765.       m.r[2].x * v.x + m.r[2].y * v.y + m.r[2].z * v.z + m.r[2].w * v.w,
  766.       m.r[3].x * v.x + m.r[3].y * v.y + m.r[3].z * v.z + m.r[3].w * v.w);
  767. }
  768. // multiply row vector by a 4x4 matrix
  769. template<class T> Vector4<T> operator*(const Vector4<T>& v, const Matrix4<T>& m)
  770. {
  771.     return Vector4<T>(m.r[0].x * v.x + m.r[1].x * v.y + m.r[2].x * v.z + m.r[3].x * v.w,
  772.                       m.r[0].y * v.x + m.r[1].y * v.y + m.r[2].y * v.z + m.r[3].y * v.w,
  773.                       m.r[0].z * v.x + m.r[1].z * v.y + m.r[2].z * v.z + m.r[3].z * v.w,
  774.                       m.r[0].w * v.x + m.r[1].w * v.y + m.r[2].w * v.z + m.r[3].w * v.w);
  775. }
  776. template<class T> Matrix4<T> Matrix4<T>::transpose() const
  777. {
  778.     return Matrix4<T>(Vector4<T>(r[0].x, r[1].x, r[2].x, r[3].x),
  779.                       Vector4<T>(r[0].y, r[1].y, r[2].y, r[3].y),
  780.                       Vector4<T>(r[0].z, r[1].z, r[2].z, r[3].z),
  781.                       Vector4<T>(r[0].w, r[1].w, r[2].w, r[3].w));
  782. }
  783. template<class T> Matrix4<T> operator*(const Matrix4<T>& a,
  784.                                        const Matrix4<T>& b)
  785. {
  786. #define MATMUL(R, C) (a[R].x * b[0].C + a[R].y * b[1].C + a[R].z * b[2].C + a[R].w * b[3].C)
  787.     return Matrix4<T>(Vector4<T>(MATMUL(0, x), MATMUL(0, y), MATMUL(0, z), MATMUL(0, w)),
  788.                       Vector4<T>(MATMUL(1, x), MATMUL(1, y), MATMUL(1, z), MATMUL(1, w)),
  789.                       Vector4<T>(MATMUL(2, x), MATMUL(2, y), MATMUL(2, z), MATMUL(2, w)),
  790.                       Vector4<T>(MATMUL(3, x), MATMUL(3, y), MATMUL(3, z), MATMUL(3, w)));
  791. #undef MATMUL
  792. }
  793. template<class T> Matrix4<T> operator+(const Matrix4<T>& a, const Matrix4<T>& b)
  794. {
  795.     return Matrix4<T>(a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]);
  796. }
  797. // Compute inverse using Gauss-Jordan elimination; caller is responsible
  798. // for ensuring that the matrix isn't singular.
  799. template<class T> Matrix4<T> Matrix4<T>::inverse() const
  800. {
  801.     Matrix4<T> a(*this);
  802.     Matrix4<T> b(Matrix4<T>::identity());
  803.     int i, j;
  804.     int p;
  805.     for (j = 0; j < 4; j++)
  806.     {
  807.         p = j;
  808.         for (i = j + 1; i < 4; i++)
  809.         {
  810.             if (fabs(a.r[i][j]) > fabs(a.r[p][j]))
  811.                 p = i;
  812.         }
  813.         // Swap rows p and j
  814.         Vector4<T> t = a.r[p];
  815.         a.r[p] = a.r[j];
  816.         a.r[j] = t;
  817.         t = b.r[p];
  818.         b.r[p] = b.r[j];
  819.         b.r[j] = t;
  820.         T s = a.r[j][j];  // if s == 0, the matrix is singular
  821.         a.r[j] *= (1.0f / s);
  822.         b.r[j] *= (1.0f / s);
  823.         // Eliminate off-diagonal elements
  824.         for (i = 0; i < 4; i++)
  825.         {
  826.             if (i != j)
  827.             {
  828.                 b.r[i] -= a.r[i][j] * b.r[j];
  829.                 a.r[i] -= a.r[i][j] * a.r[j];
  830.             }
  831.         }
  832.     }
  833.     return b;
  834. }
  835. #endif // _VECMATH_H_