如何在子弹物理中获得刚体在 0 到 360 之间的欧拉旋转?

Posted

技术标签:

【中文标题】如何在子弹物理中获得刚体在 0 到 360 之间的欧拉旋转?【英文标题】:How to get the Euler rotation of a rigid body between 0 to 360 in Bullet Physics? 【发布时间】:2015-07-04 08:02:51 【问题描述】:

我目前正在尝试获取对象的旋转。我正在使用 C++ 和子弹物理。这是我的代码:

btScalar x, y, z;
body[0]->getCenterOfMassTransform().getBasis().getEulerZYX(z, y, x);

但是,当我顺时针旋转对象时,我从 y(y 在 Bullet 中垂直)轴得到的数字从 0 到 -90 到 0 到 90,最后每四分之一旋转回到 0。它很接近,但我需要的是它从 0 到 360 一直走。

【问题讨论】:

Converting yaw Euler angles in range [-90, 90] to [0, 360]的可能重复 【参考方案1】:

子弹documentation 说:

void    getEulerZYX (btScalar &yaw, btScalar &pitch, btScalar &roll, unsigned int solution_number=1) const 

solution_number Which solution of two possible solutions ( 1 or 2) are possible values 

这是因为欧拉角不明确。您尝试过解决方案 2 吗?

【讨论】:

感谢您的快速响应。我尝试了解决方案 2,它更接近但仍然不完美。现在,当我转动物体时,我得到的结果是 180 到 270 到 180 到 90区分 0/360 和 180。还有其他想法吗? 一些可能没有帮助的东西。我正在查看返回的 y 值。但是,当模拟开始且 y 值为 180 时,z 和 x 值分别为 -180 和 180。半转后,当 y 值再次变为 180 时,x 和 z 都为 0。我意识到我很可能会使用它来破解解决方案,但我真的很想了解它是如何工作的,而不是仅仅将它破解在一起。是否有一个方程用于获得使用 3 个值而不仅仅是 y 的旋转? 有两种解决方案。使用该功能,您可以获得两者并根据您的标准选择您更喜欢的解决方案。从技术上讲,它们是相同的。如果你想旋转你的身体向后看,你可以简单地转动 180°。或者你可能想做半个前滚,然后围绕你的腹部点旋转以再次直立。我赞成第一个,但就结果而言,后者是相同的。 :-) 对,这是有道理的。但是问题依然存在,是否有可能实现绕垂直轴0-360度的旋转? 当然,您可以通过向任何(负)角度添加 360° 来随意更改这两种解决方案。【参考方案2】:

我遇到了同样的问题。我将 LibGDX 与 Bullet 引擎一起使用,所以我的代码示例在 Java 上,但我确信它也可以在 C++ 上运行。这是我的解决方案(针对 Z 轴):

body.getWorldTransform().getRotation(mRotation);

// That gives you an angle in all range but excluding (85, 95) and (-95, 85). For other axis you can try to get Pitch or Yaw.
float roll = mRotation.getRoll();

// That gives you an angle in range [0, 240). Clockwise and counterclockwise directions isn't detected. 
float angle = mRotation.getAngleAround(0, 0, 1);

// Usually 0, but on (85, 95) and (-95, 85) becomes 1 and -1. 
int gimbalPole = mRotation.getGimbalPole();

// Using roll (pitch/yaw for other axis) if it's defined, and using angle with gimble pole otherwise.
float rotation = (gimbalPole == 0) ? roll : angle * gimbalPole;

获得的旋转将在 (-180, 180) 范围内。它可以很容易地转换为 [0, 360) 范围:

if (rotation < 0) rotation += 360;

【讨论】:

以上是关于如何在子弹物理中获得刚体在 0 到 360 之间的欧拉旋转?的主要内容,如果未能解决你的问题,请参考以下文章

如何在子弹物理引擎中对身体应用旋转?

子弹物理和 OpenGL 将方向转换为前、上和右

cocos2dx 3.X刚体update穿透问题。刚体A在update中通过摇杆移动,设置的和刚体

Libgdx 子弹偏移原点

您如何在子弹物理引擎中模拟传送带?

Box2d刚体轨迹预测