| ||||
| ||||
| ||||
float Inverse(CLAYMATRIX& mOut, const CLAYMATRIX& rhs)
...{
CLAYMATRIX m(rhs);
DWORD is[4];
DWORD js[4];
float fDet = 1.0f;
int f = 1;
for (int k = 0; k < 4; k ++)
...{
// 第一步,全选主元
float fMax = 0.0f;
for (DWORD i = k; i < 4; i ++)
...{
for (DWORD j = k; j < 4; j ++)
...{
const float f = Abs(m(i, j));
if (f > fMax)
...{
fMax = f;
is[k] = i;
js[k] = j;
}
}
}
if (Abs(fMax) < 0.0001f)
return 0;
if (is[k] != k)
...{
f = -f;
swap(m(k, 0), m(is[k], 0));
swap(m(k, 1), m(is[k], 1));
swap(m(k, 2), m(is[k], 2));
swap(m(k, 3), m(is[k], 3));
}
if (js[k] != k)
...{
f = -f;
swap(m(0, k), m(0, js[k]));
swap(m(1, k), m(1, js[k]));
swap(m(2, k), m(2, js[k]));
swap(m(3, k), m(3, js[k]));
}
// 计算行列值
fDet *= m(k, k);
// 计算逆矩阵
// 第二步
m(k, k) = 1.0f / m(k, k);
// 第三步
for (DWORD j = 0; j < 4; j ++)
...{
if (j != k)
m(k, j) *= m(k, k);
}
// 第四步
for (DWORD i = 0; i < 4; i ++)
...{
if (i != k)
...{
for (j = 0; j < 4; j ++)
...{
if (j != k)
m(i, j) = m(i, j) - m(i, k) * m(k, j);
}
}
}
// 第五步
for (i = 0; i < 4; i ++)
...{
if (i != k)
m(i, k) *= -m(k, k);
}
}
for (k = 3; k >= 0; k --)
...{
if (js[k] != k)
...{
swap(m(k, 0), m(js[k], 0));
swap(m(k, 1), m(js[k], 1));
swap(m(k, 2), m(js[k], 2));
swap(m(k, 3), m(js[k], 3));
}
if (is[k] != k)
...{
swap(m(0, k), m(0, is[k]));
swap(m(1, k), m(1, is[k]));
swap(m(2, k), m(2, is[k]));
swap(m(3, k), m(3, is[k]));
}
}
mOut = m;
return fDet * f;
}
比较
| 原算法 | 原算法(经过高度优化) | 新算法 | |
|---|---|---|---|
| 加法次数 | 103 | 61 | 39 |
| 乘法次数 | 170 | 116 | 69 |
| 需要额外空间 | 16 * sizeof(float) | 34 * sizeof(float) | 25 * sizeof(float) |
结果不言而喻吧。
本文介绍了一种用于3D程序的高效矩阵求逆算法——全选主元高斯-约旦法,该方法通过减少乘法和加法次数显著提高了性能。
17万+

被折叠的 条评论
为什么被折叠?



