Go to the documentation of this file.00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009 #include "vgui_invert_homg4x4.h"
00010
00011 static bool is_diagonal(double const * const *M)
00012 {
00013 for (unsigned i=0; i<4; ++i)
00014 for (unsigned j=0; j<4; ++j)
00015 if ( (i != j) && (M[i][j] != 0) )
00016 return false;
00017 return true;
00018 }
00019
00020
00021 static bool is_trans_scale(double const * const *M)
00022 {
00023 return M[0][1] == 0 && M[0][2] == 0 &&
00024 M[1][0] == 0 && M[1][2] == 0 &&
00025 M[2][0] == 0 && M[2][1] == 0 &&
00026 M[3][0] == 0 && M[3][1] == 0 && M[3][2] == 0;
00027 }
00028
00029
00030 static double const * const * detA_inverseA(double const * const *A)
00031 {
00032 static double data[4][4]={
00033 { A[1][1]*A[2][2]*A[3][3]-A[1][1]*A[2][3]*A[3][2]-A[2][1]*A[1][2]*A[3][3]
00034 +A[2][1]*A[1][3]*A[3][2]+A[3][1]*A[1][2]*A[2][3]-A[3][1]*A[1][3]*A[2][2],
00035 -A[0][1]*A[2][2]*A[3][3]+A[0][1]*A[2][3]*A[3][2]+A[2][1]*A[0][2]*A[3][3]
00036 -A[2][1]*A[0][3]*A[3][2]-A[3][1]*A[0][2]*A[2][3]+A[3][1]*A[0][3]*A[2][2],
00037 A[0][1]*A[1][2]*A[3][3]-A[0][1]*A[1][3]*A[3][2]-A[1][1]*A[0][2]*A[3][3]
00038 +A[1][1]*A[0][3]*A[3][2]+A[3][1]*A[0][2]*A[1][3]-A[3][1]*A[0][3]*A[1][2],
00039 -A[0][1]*A[1][2]*A[2][3]+A[0][1]*A[1][3]*A[2][2]+A[1][1]*A[0][2]*A[2][3]
00040 -A[1][1]*A[0][3]*A[2][2]-A[2][1]*A[0][2]*A[1][3]+A[2][1]*A[0][3]*A[1][2] },
00041 {-A[1][0]*A[2][2]*A[3][3]+A[1][0]*A[2][3]*A[3][2]+A[2][0]*A[1][2]*A[3][3]
00042 -A[2][0]*A[1][3]*A[3][2]-A[3][0]*A[1][2]*A[2][3]+A[3][0]*A[1][3]*A[2][2],
00043 A[0][0]*A[2][2]*A[3][3]-A[0][0]*A[2][3]*A[3][2]-A[2][0]*A[0][2]*A[3][3]
00044 +A[2][0]*A[0][3]*A[3][2]+A[3][0]*A[0][2]*A[2][3]-A[3][0]*A[0][3]*A[2][2],
00045 -A[0][0]*A[1][2]*A[3][3]+A[0][0]*A[1][3]*A[3][2]+A[1][0]*A[0][2]*A[3][3]
00046 -A[1][0]*A[0][3]*A[3][2]-A[3][0]*A[0][2]*A[1][3]+A[3][0]*A[0][3]*A[1][2],
00047 A[0][0]*A[1][2]*A[2][3]-A[0][0]*A[1][3]*A[2][2]-A[1][0]*A[0][2]*A[2][3]
00048 +A[1][0]*A[0][3]*A[2][2]+A[2][0]*A[0][2]*A[1][3]-A[2][0]*A[0][3]*A[1][2] },
00049 { A[1][0]*A[2][1]*A[3][3]-A[1][0]*A[2][3]*A[3][1]-A[2][0]*A[1][1]*A[3][3]
00050 +A[2][0]*A[1][3]*A[3][1]+A[3][0]*A[1][1]*A[2][3]-A[3][0]*A[1][3]*A[2][1],
00051 -A[0][0]*A[2][1]*A[3][3]+A[0][0]*A[2][3]*A[3][1]+A[2][0]*A[0][1]*A[3][3]
00052 -A[2][0]*A[0][3]*A[3][1]-A[3][0]*A[0][1]*A[2][3]+A[3][0]*A[0][3]*A[2][1],
00053 A[0][0]*A[1][1]*A[3][3]-A[0][0]*A[1][3]*A[3][1]-A[1][0]*A[0][1]*A[3][3]
00054 +A[1][0]*A[0][3]*A[3][1]+A[3][0]*A[0][1]*A[1][3]-A[3][0]*A[0][3]*A[1][1],
00055 -A[0][0]*A[1][1]*A[2][3]+A[0][0]*A[1][3]*A[2][1]+A[1][0]*A[0][1]*A[2][3]
00056 -A[1][0]*A[0][3]*A[2][1]-A[2][0]*A[0][1]*A[1][3]+A[2][0]*A[0][3]*A[1][1] },
00057 {-A[1][0]*A[2][1]*A[3][2]+A[1][0]*A[2][2]*A[3][1]+A[2][0]*A[1][1]*A[3][2]
00058 -A[2][0]*A[1][2]*A[3][1]-A[3][0]*A[1][1]*A[2][2]+A[3][0]*A[1][2]*A[2][1],
00059 A[0][0]*A[2][1]*A[3][2]-A[0][0]*A[2][2]*A[3][1]-A[2][0]*A[0][1]*A[3][2]
00060 +A[2][0]*A[0][2]*A[3][1]+A[3][0]*A[0][1]*A[2][2]-A[3][0]*A[0][2]*A[2][1],
00061 -A[0][0]*A[1][1]*A[3][2]+A[0][0]*A[1][2]*A[3][1]+A[1][0]*A[0][1]*A[3][2]
00062 -A[1][0]*A[0][2]*A[3][1]-A[3][0]*A[0][1]*A[1][2]+A[3][0]*A[0][2]*A[1][1],
00063 A[0][0]*A[1][1]*A[2][2]-A[0][0]*A[1][2]*A[2][1]-A[1][0]*A[0][1]*A[2][2]
00064 +A[1][0]*A[0][2]*A[2][1]+A[2][0]*A[0][1]*A[1][2]-A[2][0]*A[0][2]*A[1][1] }
00065 };
00066 static double *out[4] = {data[0], data[1], data[2], data[3]};
00067 return out;
00068 }
00069
00070 bool vgui_invert_homg4x4(double const * const *M, double **Mi)
00071 {
00072 if (is_diagonal(M)) {
00073
00074
00075
00076
00077
00078 for (unsigned i=0; i<4; ++i)
00079 for (unsigned j=0; j<4; ++j)
00080 Mi[i][j] = (i==j ? 1.0/M[i][i] : 0);
00081 return true;
00082 }
00083
00084 if (is_trans_scale(M)) {
00085
00086
00087
00088
00089 Mi[0][0] = 1/M[0][0]; Mi[0][1] = 0; Mi[0][2] = 0; Mi[0][3] = -M[0][3]/M[0][0];
00090 Mi[1][0] = 0; Mi[1][1] = 1/M[1][1]; Mi[1][2] = 0; Mi[1][3] = -M[1][3]/M[1][1];
00091 Mi[2][0] = 0; Mi[2][1] = 0; Mi[2][2] = 1/M[2][2]; Mi[2][3] = -M[2][3]/M[2][2];
00092 Mi[3][0] = 0; Mi[3][1] = 0; Mi[3][2] = 0; Mi[3][3] = 1/M[3][3];
00093 return true;
00094 }
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 double const * const *out = detA_inverseA(M);
00105 for (unsigned i=0; i<4; ++i)
00106 for (unsigned j=0; j<4; ++j)
00107 Mi[i][j] = out[i][j];
00108
00109 return true;
00110 }
00111
00112 bool vgui_invert_homg4x4(double const A[4][4], double B[4][4])
00113 {
00114 double const *A_[4] = {A[0], A[1], A[2], A[3]};
00115 double *B_[4] = {B[0], B[1], B[2], B[3]};
00116 return vgui_invert_homg4x4(A_, B_);
00117 }