c++ - 4x4 矩阵重置缩放?

标签 c++ opengl

使用 C++/OpenGL。
例如,在光标位置缩放相机:

Vector3 target = GetScreenToWorldPosition(in_position);

Matrix4 s(MATRIX4_IDENTITY);
s.SetScale(0.12648); /// Arbitrary value for simplicity sake.

Matrix4 t(MATRIX4_IDENTITY);
t.SetTranslation(target);

Matrix4 tMinus(MATRIX4_IDENTITY);
tMinus.SetTranslation(-target);

Camera *camera = GetCurrentCamera();
Matrix4 matrix = camera->GetWorldMatrix();
matrix *= t * s * tMinus;

l_camera->SetScale(1, 1, 1);
l_camera->SetTranslation(?);
l_camera->SetRotation(?);
有没有办法在保持绝对平移/旋转的同时重置比例?
Matrix4:
float m[16];

Row-Major:
m[00], m[01], m[02], m[03]
m[04], m[05], m[06], m[07]
m[08], m[09], m[10], m[11]
m[12], m[13], m[14], m[15]

m[00], m[04], m[08] = Cross vector
m[01], m[05], m[09] = Up vector
m[02], m[06], m[10] = Normal vector
m[12], m[13], m[14] = Translation vector
基于 rabbid76建议:
Vector3 l_scale;

l_scale.x = sqrt(m[0] * m[0] + m[4] * m[4] + m[8] * m[8]);
l_scale.y = sqrt(m[1] * m[1] + m[5] * m[5] + m[9] * m[9]);
l_scale.z = sqrt(m[2] * m[2] + m[6] * m[6] + m[10] * m[10]);

m[0] /= l_scale.x;
m[4] /= l_scale.y;
m[8] /= l_scale.z;

m[1] /= l_scale.x;
m[5] /= l_scale.y;
m[9] /= l_scale.z;

m[2] /= l_scale.x;
m[6] /= l_scale.y;
m[10] /= l_scale.z;
它看起来很有希望,但到目前为止,过去放大的现在正在缩小,反之亦然。此外,还有一些摆动效果表明有些地方不太对劲。

最佳答案

知道矩阵,您可以计算每个轴的比例。在以下cm是矩阵:

float scaleX = sqrt(cm[0][0]*cm[0][0] + cm[0][1]*cm[0][1] + cm[0][2]*cm[0][2]);
float scaleY = sqrt(cm[1][0]*cm[1][0] + cm[1][1]*cm[1][1] + cm[1][2]*cm[1][2]);
float scaleZ = sqrt(cm[2][0]*cm[2][0] + cm[2][1]*cm[2][1] + cm[2][2]*cm[2][2]);
如果要在保持绝对平移和旋转的同时“重置”比例,则需要对轴进行归一化。归一化 vector ( Unit vector ) 的长度为 1:
for (int i = 0; i < 3; ++i)
{
    cm[0][i] /= scaleX;
    cm[1][i] /= scaleY;
    cm[2][i] /= scaleZ;
}
如果 3 轴的比例相同,则 scaleX 的结果, scaleY , scaleZ也将相同。因此,您可以调整代码并只计算一个比例。

不要改变矩阵的平移。字段 12-14 包含绝对翻译。如果你改变它,立方体“移动”。
矩阵乘法不是 commutative .如果您有 2 个比例矩阵和一个平移矩阵,并按以下顺序将它们相乘:
m = scale2 * translate * scale1
然后translatescale2 缩放,但不是 scale1 .因此,您无法重置平移缩放,因为此信息将丢失。矩阵不保存其创建历史。

关于c++ - 4x4 矩阵重置缩放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64734896/

相关文章:

c++ - clang++ 链接器架构 x86_64 的 undefined symbol

鼠标释放时的 C++ 记录

c++ - 如何有效地将 float 别名为命名成员和数组元素?

计算沿任意梯度的点的颜色

linux - Clang OpenGL 和 Max

c++ - 使用 IBO/EBO 时,程序仅在创建 VAO 后调用 glBindBuffer 绑定(bind) IBO/EBO 时才有效

c++ - OpenGL reshape 函数

c++ - 使用结构化绑定(bind)标记为 const 的变量不是 const

c++ - 在 C++ 中,是否可以获取函数的返回类型以便在不调用该函数的情况下声明一个变量?

opengl - 顶点缓冲区绑定(bind)索引和统一缓冲区绑定(bind)点?