00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef MATRIX_H
00018 #define MATRIX_H
00019
00020 #include <stdio.h>
00021 #include <camvox/GMath.h>
00022
00023 namespace camvox {
00024
00037 template <class T, int H, int W>
00038 bool gauss_jordan(T m[H][W])
00039 {
00040 const double eps = 0.00000001;
00041 for (int y = 0; y < H; y++) {
00042 int maxrow = y;
00043
00044
00045 for (int y2 = y + 1; y2 < H; y2++) {
00046 if (gabs(m[y2][y]) > gabs(m[maxrow][y])) {
00047 maxrow = y2;
00048 }
00049 }
00050
00051
00052 for (int x = 0; x < W; x++) {
00053 T tmp = m[y][x];
00054 m[y][x] = m[maxrow][x];
00055 m[maxrow][x] = tmp;
00056 }
00057
00058
00059 if (gabs(m[y][y]) <= eps) {
00060 return false;
00061 }
00062
00063
00064 for (int y2 = y + 1; y2 < H; y2++) {
00065 T c = m[y2][y] / m[y][y];
00066 for (int x = y; x < W; x++) {
00067 m[y2][x] -= m[y][x] * c;
00068 }
00069 }
00070 }
00071
00072
00073 for (int y = H - 1; y >= 0; y--) {
00074 T c = 1.0 / m[y][y];
00075
00076 for (int y2 = 0; y2 < y; y2++) {
00077 for (int x = W - 1; x >= y; x--) {
00078 m[y2][x] -= m[y][x] * m[y2][y] * c;
00079 }
00080 }
00081 m[y][y] *= c;
00082
00083
00084 for (int x = H; x < W; x++) {
00085 m[y][x] *= c;
00086 }
00087 }
00088
00089 return true;
00090 }
00091
00096 template <class T>
00097 class TMatrix {
00098 public:
00099 T m[4][4];
00100
00103 TMatrix(void) {
00104 for (int r = 0; r < 4; r++) {
00105 for (int c = 0; c < 4; c++) {
00106 m[r][c] = (r == c) ? 1.0 : 0.0;
00107 }
00108 }
00109 }
00110
00113 TMatrix operator*(const T &other) const {
00114 TMatrix result;
00115
00116 for (int r = 0; r < 4; r++) {
00117 for (int c = 0; c < 4; c++) {
00118 result.m[r][c] = other * m[r][0];
00119 }
00120 }
00121 return result;
00122 }
00123
00126 TMatrix operator*(const TMatrix &other) const {
00127 TMatrix result;
00128
00129 for (int r = 0; r < 4; r++) {
00130 for (int c = 0; c < 4; c++) {
00131 result.m[r][c] =
00132 m[r][0] * other.m[0][c] +
00133 m[r][1] * other.m[1][c] +
00134 m[r][2] * other.m[2][c] +
00135 m[r][3] * other.m[3][c];
00136 }
00137 }
00138 return result;
00139 }
00140
00143 Vector operator*(const Vector &other) const {
00144 Vector result;
00145
00146 result.x = other.x * m[0][0] + other.y * m[0][1] + other.z * m[0][2] + other.w * m[0][3];
00147 result.y = other.x * m[1][0] + other.y * m[1][1] + other.z * m[1][2] + other.w * m[1][3];
00148 result.z = other.x * m[2][0] + other.y * m[2][1] + other.z * m[2][2] + other.w * m[2][3];
00149 result.w = other.x * m[3][0] + other.y * m[3][1] + other.z * m[3][2] + other.w * m[3][3];
00150 return result;
00151 }
00152
00156 IntervalVector operator*(const IntervalVector &other) const {
00157 IntervalVector result;
00158
00159 result.x = other.x * m[0][0] + other.y * m[0][1] + other.z * m[0][2] + other.w * m[0][3];
00160 result.y = other.x * m[1][0] + other.y * m[1][1] + other.z * m[1][2] + other.w * m[1][3];
00161 result.z = other.x * m[2][0] + other.y * m[2][1] + other.z * m[2][2] + other.w * m[2][3];
00162 result.w = other.x * m[3][0] + other.y * m[3][1] + other.z * m[3][2] + other.w * m[3][3];
00163 return result;
00164 }
00165
00168 TMatrix invert(void) const {
00169 double a[4][8];
00170 TMatrix result;
00171
00172
00173 for (int r = 0; r < 4; r++) {
00174 for (int c = 0; c < 4; c++) {
00175
00176 a[r][c] = m[r][c];
00177
00178 a[r][c+4] = (r == c) ? 1.0 : 0.0;
00179 }
00180 }
00181
00182 if (!gauss_jordan<T, 4, 8>(a)) {
00183 fprintf(stderr, "Error: Matrix is singular\n");
00184 }
00185
00186
00187 for (int r = 0; r < 4; r++) {
00188 for (int c = 0; c < 4; c++) {
00189
00190
00191 result.m[r][c] = a[r][c+4];
00192 }
00193 }
00194
00195 return result;
00196 }
00197
00203 TMatrix translate(const Vector &v) const {
00204 TMatrix B = TMatrix();
00205
00206 B.m[0][3] = v.x;
00207 B.m[1][3] = v.y;
00208 B.m[2][3] = v.z;
00209 return B * (*this);
00210 }
00211
00217 TMatrix scale(const Vector &v) const {
00218 TMatrix B = TMatrix();
00219
00220 B.m[0][0] = v.x;
00221 B.m[1][1] = v.y;
00222 B.m[2][2] = v.z;
00223 return B * (*this);
00224 }
00225
00234 TMatrix rotate(const TVector<T> &v, double _angle) const {
00235 double angle = -_angle;
00236 TMatrix B = TMatrix();
00237 TVector<T> nv = v.normalize();
00238
00239 fprintf(stderr, "%lf, %lf, %lf\n", nv.x, nv.y, nv.z);
00240
00241 B.m[0][0] = (1.0 - gcos(angle)) * (nv.x * nv.x) + ( gcos(angle));
00242 B.m[0][1] = (1.0 - gcos(angle)) * (nv.x * nv.y) + (nv.z * gsin(angle));
00243 B.m[0][2] = (1.0 - gcos(angle)) * (nv.x * nv.z) - (nv.y * gsin(angle));
00244 B.m[1][0] = (1.0 - gcos(angle)) * (nv.x * nv.y) - (nv.z * gsin(angle));
00245 B.m[1][1] = (1.0 - gcos(angle)) * (nv.y * nv.y) + ( gcos(angle));
00246 B.m[1][2] = (1.0 - gcos(angle)) * (nv.y * nv.z) + (nv.x * gsin(angle));
00247 B.m[2][0] = (1.0 - gcos(angle)) * (nv.x * nv.z) + (nv.y * gsin(angle));
00248 B.m[2][1] = (1.0 - gcos(angle)) * (nv.y * nv.z) - (nv.x * gsin(angle));
00249 B.m[2][2] = (1.0 - gcos(angle)) * (nv.z * nv.z) + ( gcos(angle));
00250 return B * (*this);
00251 }
00252 };
00253
00254 typedef TMatrix<double> Matrix;
00255
00256 }
00257 #endif