【发布时间】:2014-12-16 04:00:53
【问题描述】:
我在理解矩阵时遇到了问题。如果我将矩阵围绕 X 轴旋转 90 度,它工作正常,但是,如果我将它围绕 Y 轴旋转 90 度,它实际上会在 Z 轴上旋转它。我猜每次旋转后轴都会移动。如何使用原始轴进行第二次(或更多次)旋转?这叫局部和全局旋转吗?
【问题讨论】:
我在理解矩阵时遇到了问题。如果我将矩阵围绕 X 轴旋转 90 度,它工作正常,但是,如果我将它围绕 Y 轴旋转 90 度,它实际上会在 Z 轴上旋转它。我猜每次旋转后轴都会移动。如何使用原始轴进行第二次(或更多次)旋转?这叫局部和全局旋转吗?
【问题讨论】:
在旋转之间添加“glLoadIdentity”。
【讨论】:
glLoadIdentity 根本没有帮助。这会将矩阵清除为单位,然后下一次旋转将乘以该单位矩阵。实际上,这意味着唯一能做任何事情的转换将是最后一次执行的转换。
您不会“旋转”矩阵。您通过乘法应用旋转变换矩阵。是的,每次调用 OpenGL 矩阵操作函数时,结果都将用作下一次变换乘法的输入。
绕 X 轴旋转 90° 会将 Y 轴映射到 Z,将 Z 轴映射到 -Y,这就是您所观察到的。所以接下来发生的任何转变都是从这个开始的。
要么使用 glLoadIdentity 重新为每个对象构建整个转换以重置为标识,要么使用 glPushMatrix / glPopMatrix 创建“转换块”的层次结构。或者更好的是,完全放弃 OpenGL 内置矩阵堆栈,并将其替换为适当的矩阵数学库,如 GLM、Eigen 或类似库。
【讨论】:
在实践中,克服这个问题的最佳方法是使用四元数,这有点数学。你是对的;如果你将它围绕 Y 旋转 90 度,而不是你想围绕 Z 旋转它,你将围绕 X 旋转。
这是一个将欧拉角转换为四元数的好来源:http://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToQuaternion/
下面是如何用四元数制作一个旋转矩阵: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/
填满矩阵后,可以调用glMultMatrix( qMatrix);进行乘法运算。
【讨论】:
昨晚想了想找到了答案(我好像总是这样……)
我有一个名为 GLMatrix 的对象来保存矩阵:
class GLMatrix {
public float m[] = new float[16];
...includes many methods to deal with matrix...
}
并且它有一个添加旋转的功能:
public void addRotate2(float angle, float ax, float ay, float az) {
GLMatrix tmp = new GLMatrix();
tmp.setAA(angle, ax, ay, az);
mult4x4(tmp);
}
如您所见,我使用轴角 (AA),它使用 setAA() 应用于临时矩阵,然后乘以当前矩阵。 昨晚我想如果我将AA的输入向量旋转当前矩阵然后创建临时矩阵和倍数。
所以它看起来像这样:
public void addRotate4(float angle, float ax, float ay, float az) {
GLMatrix tmp = new GLMatrix();
GLVector3 vec = new GLVector3();
vec.v[0] = ax;
vec.v[1] = ay;
vec.v[2] = az;
mult(vec); //multiple vector by current matrix
tmp.setAA(angle, vec.v[0], vec.v[1], vec.v[2]);
mult4x4(tmp);
}
它按预期工作! addRotate4() 函数现在在原始轴上旋转。
【讨论】: