簡體   English   中英

4x4 矩陣重置縮放?

[英]4x4 matrix reset scaling?

使用 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]);

如果要在保持絕對平移和旋轉的同時“重置”比例,則需要對軸進行歸一化。 歸一化向量(單位向量)的長度為 1:

for (int i = 0; i < 3; ++i)
{
    cm[0][i] /= scaleX;
    cm[1][i] /= scaleY;
    cm[2][i] /= scaleZ;
}

如果 3 軸的比例相同,則scaleXscaleYscaleZ的結果也將相同。 因此,您可以調整代碼並只計算一個比例。


不要改變矩陣的平移。 字段 12-14 包含絕對翻譯。 如果你改變它,立方體“移動”。

矩陣乘法不是可交換的 如果您有 2 個比例矩陣和一個平移矩陣,並按以下順序將它們相乘:

m = scale2 * translate * scale1

然后translate使用scale2縮放,但不使用scale1 因此,您無法重置平移縮放,因為此信息將丟失。 矩陣不保存其創建歷史。

您可以將轉換存儲為 3 個向量/矩陣,用於平移、旋轉和縮放,並在需要時從它們創建一個矩陣:

void CreateMatrix(Matrix4 translation, Matrix4 rotation, Matrix4 scale, Matrix4& out) {
    out = scale * rotation * translation;
}

void Translate(Matrix4 translate, Matrix4& translation, Matrix4& rotation, Matrix4& scale) {
    translation *= translate;
}

void Rotate(Matrix4 rotate, Matrix4& translation, Matrix4& rotation, Matrix4& scale) {
    translation *= rotate;
    scale *= rotate;
    rotation *= rotate;
}

void Scale(Matrix4 scaling, Matrix4& translation, Matrix4& rotation, Matrix4& scale) {
    translation *= scaling;
    scale *= scaling;
}

要重置比例,請將比例矩陣設置為身份/比例向量為零。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM