从this thread实现答案我有这个代码将deltayaw,deltaroll和deltapitch角度转换为一个角度并围绕它旋转一个节点。作为参数的角度是角度的瞬时变化,因为给出整个角度会忽略方向的变化。
public static void matrixRotate(Group n, double deltaroll, double deltapitch, double deltayaw){
double A11 = Math.cos(deltaroll)*Math.cos(deltayaw);
double A12 = Math.cos(deltapitch)*Math.sin(deltaroll)+Math.cos(deltaroll)*Math.sin(deltapitch)*Math.sin(deltayaw);
double A13 = Math.sin(deltaroll)*Math.sin(deltapitch)-Math.cos(deltaroll)*Math.cos(deltapitch)*Math.sin(deltayaw);
double A21 =-Math.cos(deltayaw)*Math.sin(deltaroll);
double A22 = Math.cos(deltaroll)*Math.cos(deltapitch)-Math.sin(deltaroll)*Math.sin(deltapitch)*Math.sin(deltayaw);
double A23 = Math.cos(deltaroll)*Math.sin(deltapitch)+Math.cos(deltapitch)*Math.sin(deltaroll)*Math.sin(deltayaw);
double A31 = Math.sin(deltayaw);
double A32 =-Math.cos(deltayaw)*Math.sin(deltapitch);
double A33 = Math.cos(deltapitch)*Math.cos(deltayaw);
double d = Math.acos((A11+A22+A33-1d)/2d);
if(d!=0d){
double den=2d*Math.sin(d);
Point3D p= new Point3D((A32-A23)/den,(A13-A31)/den,(A21-A12)/den);
Rotate r = new Rotate();
r.setAxis(p);
r.setAngle(Math.toDegrees(d));
n.getTransforms().add(r);
Transform all = n.getLocalToSceneTransform();
n.getTransforms().clear();
n.getTransforms().add(all);
}
}
(我使用旋转,因为我需要始终围绕原点而不是中心旋转对象)
现在这会产生一个问题,因为我不再能够获得实际的俯仰角,俯仰角和偏航角。
我曾经像这样跟踪它们(没有考虑到方向的变化):
roll +=deltaroll;
pitch += deltapitch;
yaw += deltayaw;
后来我提出了这个,这更准确一些,但是如果没有直接修改角度(在n.getTransforms()之后插入),则不会跟踪发生的变化。在主要代码段中添加(全部):
roll+= Math.toDegrees(d)*((A32-A23)/den);
pitch += Math.toDegrees(d)*((A13-A31)/den);
yaw += Math.toDegrees(d)*((A21-A12)/den);
我一直在寻找解决方案,并发现this answer应该给出最终转换的角度,但我无法让它适用于所有角度。
double xx = n.getLocalToSceneTransform().getMxx();
double xy = n.getLocalToSceneTransform().getMxy();
double roll = Math.atan2(-xy, xx);
我想要得到的是相对于场景的协调系统的全角度(由不同方向的三角形角度构成的变换合成)。我对此非常不好,所以所有帮助都会很棒。
答案 0 :(得分:1)
如果您想在几次旋转后的任何阶段获得俯仰,偏转和滚转角度,您可以从3D模型的变换矩阵中获取它们。
如果您在几次旋转后查看转换矩阵:
Transform T = model3D.getLocalToSceneTransform();
System.out.println(T);
你会看到这样的东西:
Transform [
0.9034731871219395, -0.4260296991535005, -0.04727468234587054, 1.4044414829046357
0.3743586809560477, 0.837958815679334, -0.39709016761704913, 0.5234811188037405
0.2087864414768669, 0.3410626315861443, 0.9165612381019399, -1.1277640590168572
]
如果你想要角度,你只需要将这个矩阵与这个answer中的矩阵进行比较:
正如您已经说过的,要获得滚动角度,您可以使用T.getMxx()
和T.getMyx()
:
double roll = Math.atan2(-T.getMyx(),T.getMxx());
现在,对于音高,你可以用同样的方式使用T.getMzy()
和T.getMzz()
:
double pitch = Math.atan2(-T.getMzy(),T.getMzz());
最后,对于偏航,请使用T.getMzx()
,T.getMzy()
和T.getMzz()
:
double yaw = Math.atan2(T.getMzx(),Math.sqrt(T.getMzy()*T.getMzy()+T.getMzz()*T.getMzz()));
这将为上面的矩阵提供您要寻找的角度(以弧度表示):
roll: -0.39281984604895126
pitch: -0.356235553820928
yaw: 0.21033388848106072