Как получить эйлерово вращение твердого тела от 0 до 360 в Bullet Physics?

В настоящее время я пытаюсь получить вращение объекта. Я использую C++ и Bullet Physics. Это мой код:

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

Однако, когда я поворачиваю объект вокруг по часовой стрелке, число, которое я получаю от оси y (y - вертикальная по пули), изменяется от 0 до -90 до 0 до 90 и, наконец, возвращается к 0 для каждого поворота на четверть. Это близко, но мне нужно, чтобы он прошел весь путь от 0 до 360.

2 ответа

Пуля документации говорит:

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?

У меня такая же проблема. Я использую 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;
Другие вопросы по тегам