我正在使用 Direct3D 9 开发一个 3 x 3 x 3 魔方,用户可以通过单击并拖动图层来旋转魔方的一层,旋转看起来像这样
旋转的底层实现是通过矩阵乘法计算的,每次用户拖动鼠标左键时,我都会生成旋转角度和旋转轴,并用它们计算旋转矩阵,然后将旋转矩阵与单位立方体的世界矩阵相乘在当前层,代码如下
world Rotate之前的世界“Cube”代表单位立方体类,而不是魔方,一个魔方是由27个单位立方体组成的,我通过旋转该层中的所有单位立方体来旋转一层。
void Cube::Rotate(D3DXVECTOR3& axis, float angle)
{
// Calculate the rotation matrix
D3DXMATRIX rotate_matrix;
D3DXMatrixRotationAxis(&rotate_matrix, &axis, angle);
// This may cause the matrix multiplication accumulate errors, how to fix it?
world_matrix_ *= rotate_matrix;
}
但这段代码是邪恶的,有时当我旋转图层时,它消失了,见下图,很难重现,但 id 确实发生了。
我知道这可能是由矩阵乘法累积错误引起的。所以我在图层消失之前转储了世界矩阵,如下所示,我们可以看到矩阵中的一些数字变成了 NaN(不是数字)。
world matrix
_11:0.999996 _12:0.000000 _13:0.000000 _14:0.000000
_21:0.000000 _22:-0.508825 _23:-0.860867 _24:0.000000
_31:0.000000 _32:0.860867 _33:-0.508825 _34:0.000000
_41:0.000000 _42:0.000000 _43:0.000000 _44:1.000000
world matrix
_11:0.999996 _12:0.000000 _13:-0.000000 _14:0.000000
_21:0.000000 _22:-0.508824 _23:-0.860866 _24:0.000000
_31:-0.000000 _32:0.860868 _33:-0.508825 _34:0.000000
_41:0.000000 _42:0.000000 _43:0.000000 _44:1.000000
world matrix
_11:0.999996 _12:-0.000000 _13:-0.000000 _14:0.000000
_21:0.000000 _22:-0.508824 _23:-0.860866 _24:0.000000
_31:0.000000 _32:0.860867 _33:-0.508825 _34:0.000000
_41:0.000000 _42:0.000000 _43:0.000000 _44:1.000000
world matrix
_11:0.999996 _12:-0.000000 _13:-0.000000 _14:0.000000
_21:0.000000 _22:-0.508824 _23:-0.860866 _24:0.000000
_31:0.000000 _32:0.860867 _33:-0.508825 _34:0.000000
_41:0.000000 _42:0.000000 _43:0.000000 _44:1.000000
world matrix
_11:0.999996 _12:0.000000 _13:-0.000000 _14:0.000000
_21:0.000000 _22:-0.508824 _23:-0.860866 _24:0.000000
_31:-0.000000 _32:0.860868 _33:-0.508825 _34:0.000000
_41:0.000000 _42:0.000000 _43:0.000000 _44:1.000000
world matrix
_11:1.#QNAN0 _12:1.#QNAN0 _13:1.#QNAN0 _14:0.000000
_21:1.#QNAN0 _22:1.#QNAN0 _23:1.#QNAN0 _24:0.000000
_31:1.#QNAN0 _32:1.#QNAN0 _33:1.#QNAN0 _34:0.000000
_41:1.#QNAN0 _42:1.#QNAN0 _43:1.#QNAN0 _44:1.000000
world matrix
_11:1.#QNAN0 _12:1.#QNAN0 _13:1.#QNAN0 _14:0.000000
_21:1.#QNAN0 _22:1.#QNAN0 _23:1.#QNAN0 _24:0.000000
_31:1.#QNAN0 _32:1.#QNAN0 _33:1.#QNAN0 _34:0.000000
_41:1.#QNAN0 _42:1.#QNAN0 _43:1.#QNAN0 _44:1.000000
问题是,我知道错误是什么,但我不知道如何解决它。
- 我需要改变我的轮换方法吗?
- 我可以在图层消失之前对矩阵进行一些校正吗?
你可以下载二进制文件试试看,如果需要,我可以提供项目代码,代码很多,所以我没有放在这里。