Как правильно применить крутящий момент или угловой импульс к телу в PlayN?

Я пытался применить угловой импульс к объекту Body в PlayN, но безрезультатно. Какое бы значение (радиально) я ни вводил, угол тела никогда не меняется. Я пытался установить крутящий момент, но безрезультатно.

Пример кода, который не работает:

BodyDef def = new BodyDef();
def.type = BodyType.DYNAMIC;
Body body = world.createBody(def);

float degToRad = (float) (180 / Math.PI);
float radials = (float) (50 / degToRad);

// None of the following options work.
body.applyAngularImpulse(radials);       // Immediate angular change.
body.applyTorque(radials);               // Angular change over time.

Как я могу получить действительный объект тела, чтобы изменить его угол без ручной установки его угловой скорости (например, с помощью setAngularVelocity)?

Заранее спасибо!

Я заметил, что крутящий момент и угловая скорость сбрасываются путем вызова метода setWake, который я никогда не делаю вручную, но он вызывается классом Island:

public void setAwake(boolean flag) {
    ...
    m_angularVelocity = 0.0f;
    m_torque = 0.0f;
    ...
}

Примечание: установка угловой скорости не является опцией, потому что я полагаюсь на физическое моделирование. Я нашел статью о повороте угла Box2D, но это не изменило результат метода applyAngularImpulse.

3 ответа

Решение

Я отладил некоторые из них и пришел к выводу, что используемые мной значения были слишком низкими. При просмотре кода applyAngularImpulse я заметил несколько вещей:

public void applyAngularImpulse(float impulse) {
    if (m_type != BodyType.DYNAMIC) {
        return;
    }

    if (isAwake() == false) {
        setAwake(true);
    }
    m_angularVelocity += m_invI * impulse;
}

m_invI - это действительно низкое значение, например, 2.44882598E-4, поэтому имеет смысл, если я использую слишком низкое значение, видимого эффекта просто нет. Если рассчитать импульс из примера вопроса, умноженного на поле m_invI:

m_invI                                 = 0.00044882598 = 2.449E-4
impulse          = 50 / 180 / PI       = 0.08841941282 = 8.842E-2
m_invI * impulse = 2.449E-4 * 8.842E-2 = 0.00002165237 = 2.165E-5 <--

Это означает просто приращение угловой скорости 0,00002165237 за цикл обновления... Что слишком мало, чтобы быть заметным, как кажется.

Кроме того, просматривая форумы Box2D на предмет похожих ситуаций, я обнаружил, что лучше всего включать инерцию тела в расчет угловых импульсов. Как это:

body.applyAngularImpulse(speedValue * body.getInertia());

Инерция имеет тенденцию быть высоким значением (+4000) для меня.

Надеюсь, что это может помочь тем, у кого есть проблемы с подачей углового импульса или крутящего момента.

В моем случае я забыл позвонить

body.setFixedRotation(false);

Даже при том, что я устанавливал массу, сообщалось об инерции, равной 0, и все моменты и угловые импульсы игнорировались.

По-видимому, это исправлено по умолчанию.

У меня такая же проблема.

В моем случае я случайно поставил свои точки в CW порядке (что привело к отрицательной области и нулевой массе). Это был мой неверный код:

// incorrect version
triangleVertices.push(new B2Vec2(width / 2, 0.0)); // top
triangleVertices.push(new B2Vec2(0.0, height));    // left
triangleVertices.push(new B2Vec2(width, heightM)); // right

Это похоже на CCW, верно? Нет, не в моей системе координат (+Y не работает).

// corrected version
triangleVertices.push(new B2Vec2(width / 2, 0.0)); // top
triangleVertices.push(new B2Vec2(width, heightM)); // right
triangleVertices.push(new B2Vec2(0.0, height));    // left
Другие вопросы по тегам