diff --git a/matrix.cpp b/matrix.cpp
index 7f81a9a5..4a168202 100644
--- a/matrix.cpp
+++ b/matrix.cpp
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with libgim. If not, see .
*
- * Copyright 2011-2012 Danny Robson
+ * Copyright 2011-2014 Danny Robson
*/
#include "matrix.hpp"
@@ -26,8 +26,10 @@
using namespace util;
+//-----------------------------------------------------------------------------
+template
void
-matrix::scale (double x, double y, double z) {
+matrix::scale (T x, T y, T z) {
CHECK_HARD (is_affine ());
values[0][0] *= x;
values[1][1] *= y;
@@ -35,8 +37,10 @@ matrix::scale (double x, double y, double z) {
}
+//-----------------------------------------------------------------------------
+template
void
-matrix::translate (double x, double y, double z) {
+matrix::translate (T x, T y, T z) {
CHECK_HARD (is_affine ());
values[0][3] += x;
values[1][3] += y;
@@ -44,33 +48,37 @@ matrix::translate (double x, double y, double z) {
}
-matrix
-matrix::inverse (void) const {
- return matrix(*this).invert ();
+//-----------------------------------------------------------------------------
+template
+matrix
+matrix::inverse (void) const {
+ return matrix(*this).invert ();
}
-matrix&
-matrix::invert (void) {
+//-----------------------------------------------------------------------------
+template
+matrix&
+matrix::invert (void) {
CHECK_HARD (is_affine ());
// inv ([ M b ] == [ inv(M) -inv(M).b ]
// [ 0 1 ]) [ 0 1
// Invert the 3x3 M
- double A = (values[1][1] * values[2][2] - values[1][2] * values[2][1]);
- double B = (values[1][2] * values[2][0] - values[1][0] * values[2][2]);
- double C = (values[1][0] * values[2][1] - values[1][1] * values[2][0]);
+ T A = (values[1][1] * values[2][2] - values[1][2] * values[2][1]);
+ T B = (values[1][2] * values[2][0] - values[1][0] * values[2][2]);
+ T C = (values[1][0] * values[2][1] - values[1][1] * values[2][0]);
- double D = (values[0][2] * values[2][1] - values[0][1] * values[2][2]);
- double E = (values[0][0] * values[2][2] - values[0][2] * values[2][0]);
- double F = (values[2][0] * values[0][1] - values[0][0] * values[2][1]);
+ T D = (values[0][2] * values[2][1] - values[0][1] * values[2][2]);
+ T E = (values[0][0] * values[2][2] - values[0][2] * values[2][0]);
+ T F = (values[2][0] * values[0][1] - values[0][0] * values[2][1]);
- double G = (values[0][1] * values[1][2] - values[0][2] * values[1][1]);
- double H = (values[0][2] * values[1][0] - values[0][0] * values[1][2]);
- double K = (values[0][0] * values[1][1] - values[0][1] * values[1][0]);
+ T G = (values[0][1] * values[1][2] - values[0][2] * values[1][1]);
+ T H = (values[0][2] * values[1][0] - values[0][0] * values[1][2]);
+ T K = (values[0][0] * values[1][1] - values[0][1] * values[1][0]);
- double det = values[0][0] * A + values[0][1] * B + values[0][2] * C;
+ T det = values[0][0] * A + values[0][1] * B + values[0][2] * C;
CHECK_NEQ (det, 0.0);
values[0][0] = A / det;
@@ -84,9 +92,9 @@ matrix::invert (void) {
values[2][2] = K / det;
// Multiply the b
- double b0 = - values[0][0] * values[0][3] - values[0][1] * values[1][3] - values[0][2] * values[2][3];
- double b1 = - values[1][0] * values[0][3] - values[1][1] * values[1][3] - values[1][2] * values[2][3];
- double b2 = - values[2][0] * values[0][3] - values[2][1] * values[1][3] - values[2][2] * values[2][3];
+ T b0 = - values[0][0] * values[0][3] - values[0][1] * values[1][3] - values[0][2] * values[2][3];
+ T b1 = - values[1][0] * values[0][3] - values[1][1] * values[1][3] - values[1][2] * values[2][3];
+ T b2 = - values[2][0] * values[0][3] - values[2][1] * values[1][3] - values[2][2] * values[2][3];
values[0][3] = b0;
values[1][3] = b1;
@@ -96,9 +104,11 @@ matrix::invert (void) {
}
-matrix
-matrix::operator* (const matrix &rhs) const {
- matrix m;
+//-----------------------------------------------------------------------------
+template
+matrix
+matrix::operator* (const matrix &rhs) const {
+ matrix m;
memset (m.values, 0, sizeof (m.values));
for (unsigned i = 0; i < 4; ++i)
@@ -110,8 +120,10 @@ matrix::operator* (const matrix &rhs) const {
}
+//-----------------------------------------------------------------------------
+template
util::point<3>
-matrix::to_local (const util::point<3> &p) const {
+matrix::to_local (const util::point<3> &p) const {
CHECK_SOFT (is_affine ());
return { p.x * values[0][0] +
@@ -126,38 +138,51 @@ matrix::to_local (const util::point<3> &p) const {
}
+//-----------------------------------------------------------------------------
+template
util::point<3>
-matrix::to_global (const util::point<3> &p) const {
+matrix::to_global (const util::point<3> &p) const {
return inverse ().to_local (p);
}
-
+//-----------------------------------------------------------------------------
+template
bool
-matrix::is_affine (void) const {
- return exactly_equal (values[3][0], 0.0) &&
- exactly_equal (values[3][1], 0.0) &&
- exactly_equal (values[3][2], 0.0) &&
- exactly_equal (values[3][3], 1.0);
+matrix::is_affine (void) const {
+ return exactly_equal (values[3][0], static_cast (0)) &&
+ exactly_equal (values[3][1], static_cast (0)) &&
+ exactly_equal (values[3][2], static_cast (0)) &&
+ exactly_equal (values[3][3], static_cast (1));
}
-const matrix
-matrix::IDENTITY = { { { 1.0, 0.0, 0.0, 0.0 },
- { 0.0, 1.0, 0.0, 0.0 },
- { 0.0, 0.0, 1.0, 0.0 },
- { 0.0, 0.0, 0.0, 1.0 } } };
+//-----------------------------------------------------------------------------
+template
+const matrix
+matrix::IDENTITY = { { { 1, 0, 0, 0 },
+ { 0, 1, 0, 0 },
+ { 0, 0, 1, 0 },
+ { 0, 0, 0, 1 } } };
-const matrix
-matrix::ZEROES = { { { 0.0, 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0, 0.0 },
- { 0.0, 0.0, 0.0, 0.0 } } };
+template
+const matrix
+matrix::ZEROES = { { { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 0 } } };
+//-----------------------------------------------------------------------------
+template struct matrix;
+template struct matrix;
+
+
+//-----------------------------------------------------------------------------
+template
std::ostream&
-operator<< (std::ostream &os, const matrix &m) {
+operator<< (std::ostream &os, const matrix &m) {
os << "{ {" << m.values[0][0] << ", "
<< m.values[0][1] << ", "
<< m.values[0][2] << ", "
diff --git a/matrix.hpp b/matrix.hpp
index f14a79ec..0a5b2eeb 100644
--- a/matrix.hpp
+++ b/matrix.hpp
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with libgim. If not, see .
*
- * Copyright 2011-2012 Danny Robson
+ * Copyright 2011-2014 Danny Robson
*/
#ifndef __UTIL_MATRIX_HPP
@@ -25,27 +25,29 @@
#include
namespace util {
+ template
struct matrix {
- double values[4][4];
+ T values[4][4];
- void scale (double x, double y, double z);
- void translate (double x, double y, double z);
+ void scale (T x, T y, T z);
+ void translate (T x, T y, T z);
- matrix inverse (void) const;
- matrix& invert (void);
+ matrix inverse (void) const;
+ matrix& invert (void);
- matrix operator* (const matrix&) const;
+ matrix operator* (const matrix&) const;
point<3> to_local (const point<3> &p) const;
point<3> to_global (const point<3> &p) const;
bool is_affine (void) const;
- static const matrix IDENTITY;
- static const matrix ZEROES;
+ static const matrix IDENTITY;
+ static const matrix ZEROES;
};
}
-std::ostream& operator<< (std::ostream&, const util::matrix&);
+template
+std::ostream& operator<< (std::ostream&, const util::matrix&);
#endif