如何移动 3D 框以保持在旋转平面上?

How can I move a 3D box in order to stay on a rotating plane?

我有一个旋转平面和一个盒子。当飞机旋转并倾斜一个角度时,我希望盒子保持在平面上的相同位置。

Here飞机不倾斜,

here飞机是倾斜的,

但是盒子没有跟随平面向下。

在每次更新时,我都会渲染框,并通过 glm::translate 中给定的 vec3 进行翻译:

{
    glm::mat4 modelMatrix = glm::mat4(1);
    modelMatrix = glm::translate(modelMatrix, glm::vec3(boxOX, boxOY, boxOZ));
    modelMatrix = glm::rotate(modelMatrix, RADIANS(anglePlaneOX), glm::vec3(1, 0, 0));
    modelMatrix = glm::rotate(modelMatrix, RADIANS(anglePlaneOY), glm::vec3(0, 1, 0));
    modelMatrix = glm::rotate(modelMatrix, RADIANS(anglePlaneOZ), glm::vec3(0, 0, 1));
    modelMatrix = glm::scale(modelMatrix, glm::vec3(0.2f));
    RenderSimpleMesh(meshes["box"], shaders["ShaderLab8"], modelMatrix, glm::vec3(1, 0, 0));
}

飞机通过敲击 WASD 键移动:

    if (window->KeyHold(GLFW_KEY_W) && (anglePlaneOX > -90.0f)) {
        anglePlaneOX -= deltaTime * DELTA_SLOPE;
    }
    if (window->KeyHold(GLFW_KEY_S) && (anglePlaneOX < 90.0f)) {
        anglePlaneOX += deltaTime * DELTA_SLOPE;
    }
    if (window->KeyHold(GLFW_KEY_D) && (anglePlaneOZ > -90.0f)) {
        anglePlaneOZ -= deltaTime * DELTA_SLOPE;
    }
    if (window->KeyHold(GLFW_KEY_A) && (anglePlaneOZ < 90.0f)) {
        anglePlaneOZ += deltaTime * DELTA_SLOPE;
    }

我尝试了以下方法

当按下 A 键时:

boxOY += deltaTime * (1 - (float)cos((double)anglePlaneOZ * PI / 180));

当按下W键时:

boxOX -= deltaTime * sinf(anglePlaneOX * PI / 180);

但其中 none 似乎有效。

将盒子相应地移动到平面的数学关系是什么?

您必须进行翻译 "before" 旋转:

glm::mat4 modelMatrix = glm::mat4(1);  

modelMatrix = glm::translate(modelMatrix, glm::vec3(boxOX, boxOY, boxOZ));

modelMatrix = glm::rotate(modelMatrix, RADIANS(anglePlaneOX), glm::vec3(1, 0, 0));  
modelMatrix = glm::rotate(modelMatrix, RADIANS(anglePlaneOY), glm::vec3(0, 1, 0));  
modelMatrix = glm::rotate(modelMatrix, RADIANS(anglePlaneOZ), glm::vec3(0, 0, 1));

modelMatrix = glm::translate(modelMatrix, glm::vec3(boxOX, boxOY, boxOZ)); //  translate here

modelMatrix = glm::scale(modelMatrix, glm::vec3(0.2f));
RenderSimpleMesh(meshes["box"], shaders["ShaderLab8"], modelMatrix, glm::vec3(1, 0, 0));  

解释:

翻译矩阵如下所示:

glm::mat4 translate;
translate[0] : ( 1,  0,  0,  0 )
translate[1] : ( 0,  1,  0,  0 )
translate[2] : ( 0,  0,  1,  0 )
translate[3] : ( tx, ty, tz, 1 )

绕 Y 轴的旋转矩阵如下所示:

mat4  rotate;
float angle;
rotate[0] : ( cos(angle),  0, sin(angle), 0 )
rotate[1] : ( 0,           1, 0,          0 )
rotate[2] : ( -sin(angle), 0, cos(angle), 0 )
rotate[3] : ( 0,           0, 0,          1 ) 

translate * rotate的结果是这样的:

model[0] : ( cos(angle),  0,  sin(angle), 0 )
model[1] : ( 0,           1,  0,          0 )
model[2] : ( -sin(angle), 0,  cos(angle), 0 )
model[3] : ( tx,          ty, tz,         1 )

请注意,rotate * translate 的结果将是:

model[0] : ( cos(angle),                     0,   sin(angle),                     0 )
model[1] : ( 0,                              1,   0,                              0 )
model[2] : ( -sin(angle),                    0,   cos(angle),                     0 )
model[3] : ( cos(angle)*tx - sin(angle)*tx,  ty,  sin(angle)*tz + cos(angle)*tz,  1 )