如何移动 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 )
我有一个旋转平面和一个盒子。当飞机旋转并倾斜一个角度时,我希望盒子保持在平面上的相同位置。
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 )