|
@ -713,6 +713,46 @@ const float * GMatrix::operator[](const int idx) const |
|
|
return &m[idx*c]; |
|
|
return &m[idx*c]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GMatrix & GMatrix::SetInverse() |
|
|
|
|
|
{ |
|
|
|
|
|
//只有方阵才能求逆
|
|
|
|
|
|
assert(r == c); |
|
|
|
|
|
|
|
|
|
|
|
//并不是所有矩阵都有逆矩阵,非奇异矩阵才有逆矩阵,也就是行列式不能为0
|
|
|
|
|
|
float det = Det(*this); |
|
|
|
|
|
assert(det != 0); |
|
|
|
|
|
|
|
|
|
|
|
//构建增广矩阵
|
|
|
|
|
|
int exc = c * 2; |
|
|
|
|
|
GMatrix exM(r, exc); |
|
|
|
|
|
|
|
|
|
|
|
int i, j = 0; |
|
|
|
|
|
for (i = 0; i < exM.GetRowNum(); i++) { |
|
|
|
|
|
for (j = 0; j < exM.GetColNum(); j++) { |
|
|
|
|
|
if (j < c) { |
|
|
|
|
|
exM[i][j] = m[i*c + j]; |
|
|
|
|
|
} |
|
|
|
|
|
else { |
|
|
|
|
|
if (j - c == i) { |
|
|
|
|
|
exM[i][j] = 1.0f; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
exM = ReduceRowEchelonForm(exM); |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < exM.GetRowNum(); i++) { |
|
|
|
|
|
for (j = 0; j < exM.GetColNum(); j++) { |
|
|
|
|
|
if (j >= c) { |
|
|
|
|
|
m[i*c + (j - c)] = exM[i][j]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
GMatrix & GMatrix::SetTranspose() |
|
|
GMatrix & GMatrix::SetTranspose() |
|
|
{ |
|
|
{ |
|
|
int i, j; |
|
|
int i, j; |
|
@ -1015,6 +1055,18 @@ GMatrix Mij(const GMatrix & m, int rom, int col) |
|
|
return ret; |
|
|
return ret; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GMatrix Cij(const GMatrix & m, int r, int c) |
|
|
|
|
|
{ |
|
|
|
|
|
GMatrix ret = Mij(m, r, c); |
|
|
|
|
|
int t = pow(-1, r + c); |
|
|
|
|
|
if (t == -1) { |
|
|
|
|
|
for (int i = 0; i < ret.GetColNum(); i++) { |
|
|
|
|
|
ret[0][i] = -ret[0][i];//行列式运算的-号只能影响一行
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
float Det(const GMatrix & m) |
|
|
float Det(const GMatrix & m) |
|
|
{ |
|
|
{ |
|
|
int i = 0; |
|
|
int i = 0; |
|
@ -1031,8 +1083,11 @@ float Det(const GMatrix & m) |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
for (i = 0; i < c; i++) { |
|
|
for (i = 0; i < c; i++) { |
|
|
GMatrix t = Mij(m, 0, i); |
|
|
|
|
|
ret += pow(-1, 0+ i) * m[0][i] * Det(t); |
|
|
|
|
|
|
|
|
//GMatrix t = Mij(m, 0, i);
|
|
|
|
|
|
//ret += pow(-1, 0+ i) * m[0][i] * Det(t);
|
|
|
|
|
|
GMatrix t = Cij(m, 0, i); |
|
|
|
|
|
//cout << t << endl;
|
|
|
|
|
|
ret += m[0][i] * Det(t); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1270,3 +1325,180 @@ GQuater & GQuater::operator*=(const GQuater & rhs) |
|
|
z = nz; |
|
|
z = nz; |
|
|
return *this; |
|
|
return *this; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::operator*=(const float & s) |
|
|
|
|
|
{ |
|
|
|
|
|
w *= s; |
|
|
|
|
|
x *= s; |
|
|
|
|
|
y *= s; |
|
|
|
|
|
z *= s; |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::operator/=(const float & s) |
|
|
|
|
|
{ |
|
|
|
|
|
w /= s; |
|
|
|
|
|
x /= s; |
|
|
|
|
|
y /= s; |
|
|
|
|
|
z /= s; |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator+() const |
|
|
|
|
|
{ |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator-() const |
|
|
|
|
|
{ |
|
|
|
|
|
//return *this*-1.0f;
|
|
|
|
|
|
return GQuater(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator+(const GQuater & rhs) const |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(*this); |
|
|
|
|
|
|
|
|
|
|
|
ret += rhs; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator-(const GQuater & rhs) const |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(*this); |
|
|
|
|
|
|
|
|
|
|
|
ret -= rhs; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator*(const GQuater & rhs) const |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(*this); |
|
|
|
|
|
|
|
|
|
|
|
ret *= rhs; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator*(const float & s) const |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(*this); |
|
|
|
|
|
|
|
|
|
|
|
ret *= s; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater GQuater::operator/(const float & s) const |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(*this); |
|
|
|
|
|
|
|
|
|
|
|
ret /= s; |
|
|
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::Set(const float w, const float x, const float y, const float z) |
|
|
|
|
|
{ |
|
|
|
|
|
this->w = w; |
|
|
|
|
|
this->x = x; |
|
|
|
|
|
this->y = y; |
|
|
|
|
|
this->z = z; |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::Set(float * q, bool invOrder) |
|
|
|
|
|
{ |
|
|
|
|
|
if (invOrder) { |
|
|
|
|
|
w = q[1]; |
|
|
|
|
|
x = q[2]; |
|
|
|
|
|
y = q[3]; |
|
|
|
|
|
z = q[0]; |
|
|
|
|
|
} else { |
|
|
|
|
|
w = q[0]; |
|
|
|
|
|
x = q[1]; |
|
|
|
|
|
y = q[2]; |
|
|
|
|
|
z = q[3]; |
|
|
|
|
|
} |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool GQuater::IsUnitQuater() const |
|
|
|
|
|
{ |
|
|
|
|
|
float len = SQR(w) + SQR(x) + SQR(y) + SQR(z); |
|
|
|
|
|
return EQ(len, 1.0f, PRECISION) ? true : false; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool GQuater::IsIdentity() const |
|
|
|
|
|
{ |
|
|
|
|
|
return EQ(w,1.0f,PRECISION) && EQ(x, 0.0f, PRECISION) && EQ(y, 0.0f, PRECISION) && EQ(z, 0.0f, PRECISION); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::Normalize() |
|
|
|
|
|
{ |
|
|
|
|
|
float len = SQR(w) + SQR(x) + SQR(y) + SQR(z); |
|
|
|
|
|
w /= len; |
|
|
|
|
|
x /= len; |
|
|
|
|
|
y /= len; |
|
|
|
|
|
z /= len; |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::SetIdentitf() |
|
|
|
|
|
{ |
|
|
|
|
|
w /= 1.0f; |
|
|
|
|
|
x /= 0.0f; |
|
|
|
|
|
y /= 0.0f; |
|
|
|
|
|
z /= 0.0f; |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::SetConjugate() |
|
|
|
|
|
{ |
|
|
|
|
|
x *= -1.0f; |
|
|
|
|
|
y *= -1.0f; |
|
|
|
|
|
z *= -1.0f; |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater & GQuater::SetInverse() |
|
|
|
|
|
{ |
|
|
|
|
|
if (!IsUnitQuater()) {//如果不是单位四元数要先单位化
|
|
|
|
|
|
float len = SQR(w) + SQR(x) + SQR(y) + SQR(z); |
|
|
|
|
|
*this /= len; |
|
|
|
|
|
} |
|
|
|
|
|
SetConjugate(); |
|
|
|
|
|
return *this; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater operator*(const float & s, const GQuater & rhs) |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(rhs); |
|
|
|
|
|
ret *= s; |
|
|
|
|
|
return ret; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ostream & operator<<(ostream & os, const GQuater & q) |
|
|
|
|
|
{ |
|
|
|
|
|
os << "(" << setw(2) << q.w << ", " << setw(2) << q.x << ", " << setw(2) << q.y << ", " << setw(2) << q.z << ")"; |
|
|
|
|
|
return os; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float norm(const GQuater & q) |
|
|
|
|
|
{ |
|
|
|
|
|
float norm = SQRT(SQR(q.w) + SQR(q.x) + SQR(q.y) + SQR(q.z)); |
|
|
|
|
|
return norm; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
GQuater inv(const GQuater & q) |
|
|
|
|
|
{ |
|
|
|
|
|
GQuater ret(q); |
|
|
|
|
|
if (!ret.IsUnitQuater()) {//如果不是单位四元数要先单位化
|
|
|
|
|
|
float t = SQR(ret.w) + SQR(ret.x) + SQR(ret.y) + SQR(ret.z); |
|
|
|
|
|
ret /= t; |
|
|
|
|
|
} |
|
|
|
|
|
ret.Set(ret.w, -ret.x, -ret.y, -ret.z); |
|
|
|
|
|
return ret; |
|
|
|
|
|
} |