Adr*_*ddy 24 c++ math 3d matrix euler-angles
我正在研究2自由度(俯仰和滚动)的运动模拟器.我正在从游戏中读取变换矩阵,我需要获得角度并发送到硬件来驱动电机.由于欧拉角有奇点,我不能真正使用它们.它的行为如下:

什么时候应该这样:

我准备了在线示例以更好地显示问题:
// Get euler angles from model matrix
var mat = model.matrix;
mat.transpose();
var e = new THREE.Euler();
e.setFromRotationMatrix(mat, 'XZY');
var v = e.toVector3();
var pitch = -v.z;
var roll = -v.x;
Run Code Online (Sandbox Code Playgroud)
http://jsfiddle.net/qajro0ny/3/
据我了解,这里有两个问题.
我已经读过关于万向节锁甚至实现了euler过滤器,但是没有按预期工作.关于万向节锁的大多数建议是使用四元数,但我不能用四元数驱动物理运动(或者我可以?).
轴顺序在这里并不重要,因为更改它只会将奇点从一个轴移动到另一个轴.
我需要以其他方式处理这个问题.
我尝试用矩阵乘以轴向量,然后使用十字和点积来获得角度,但这也失败了.我认为还应该进行轴重投,以实现这一目标,但我无法弄明白.但有些事情告诉我,这是正确的方法.它是这样的:http://jsfiddle.net/qajro0ny/53/
然后我提出了不同的想法.我知道以前的位置,所以可能会做以下事情:
所以我试过了......它奏效了!在任何方向上都没有奇点,在俯仰,滚转和偏航方面完美的360度旋转.完美的解决方案!除了......它不是.帧没有同步,所以经过一段时间的角度远离他们应该是什么.我一直在考虑某种同步机制,但我认为这不是正确的方法.
它看起来像这样:http://jsfiddle.net/qajro0ny/52/
和相同的逻辑,但直接与矩阵:http://jsfiddle.net/qajro0ny/54/
我搜索了网页的高低,我已经阅读了几十篇论文和其他问题/帖子,我简直无法相信没有什么能真正起作用.
我可能不理解或遗漏某些东西,所以这里是我发现和尝试的一切:
链接:http://pastebin.com/3G0dYLvu
代码:http://pastebin.com/PiZKwE2t(我把它们放在一起,所以它很乱)
我一定是错过了什么,或者我是从错误的角度看这个.
如果您知道矩阵仅包含两个旋转(按给定顺序T = RZ * RX),那么您可以执行以下操作:
局部x轴不受第二次旋转的影响.因此,您只能使用局部x轴计算第一个角度.然后,您可以从矩阵中移除此旋转,并从其他两个轴中的任意一个计算剩余角度:
function calculateAngles() {
var mat = model.matrix;
//calculates the angle from the local x-axis
var pitch = Math.atan2(mat.elements[1], mat.elements[0]);
//this matrix is used to remove the first rotation
var invPitch = new THREE.Matrix4();
invPitch.makeRotationZ(-pitch);
//this matrix will only contain the roll rotation
// rollRot = RZ^-1 * T
// = RZ^-1 * RZ * RX
// = RX
var rollRot = new THREE.Matrix4();
rollRot.multiplyMatrices(invPitch, mat);
//calculate the remaining angle from the local y-axis
var roll = Math.atan2(rollRot.elements[6], rollRot.elements[5]);
updateSimAngles(pitch, roll);
}
Run Code Online (Sandbox Code Playgroud)
这当然只有在给定的矩阵符合要求时才有效.它不得包含第三个旋转.否则,您可能需要找到非线性最小二乘解.