Применение постоянной силы: applyForce

В физическом движке Cannon.js применение сил к телам является базовым механизмом моделирования динамики. Постоянная сила — это воздействие, которое прикладывается к телу на протяжении времени и вызывает изменение его линейной и угловой скорости в соответствии с законами механики.

Метод applyForce используется для добавления силы к телу в текущем шаге симуляции.


Сигнатура метода

body.applyForce(force, relativePoint)

Параметры:

  • force — объект CANNON.Vec3, задающий вектор силы в мировых координатах.
  • relativePoint — объект CANNON.Vec3, определяющий точку приложения силы относительно центра масс тела (в локальных координатах тела).

Принцип работы

При вызове applyForce происходит:

  1. Добавление вектора силы к суммарной силе тела (body.force).
  2. Вычисление крутящего момента (если точка приложения не совпадает с центром масс).
  3. Обновление линейного и углового ускорения на следующем шаге симуляции.

Сила действует только в рамках одного шага физического мира (world.step). Для постоянного воздействия метод необходимо вызывать на каждом кадре.


Линейное движение

Если сила приложена к центру масс, тело получает только линейное ускорение.

Пример

const force = new CANNON.Vec3(100, 0, 0);
const point = new CANNON.Vec3(0, 0, 0);

body.applyForce(force, point);

В этом случае тело начнёт ускоряться вдоль оси X без вращения.

Формула, реализуемая движком:

a = F / m

где:

  • a — ускорение,
  • F — приложенная сила,
  • m — масса тела.

Возникновение крутящего момента

Если сила приложена не к центру масс, возникает вращение.

Крутящий момент вычисляется по формуле:

τ = r × F

где:

  • τ — крутящий момент,
  • r — вектор от центра масс до точки приложения,
  • F — сила.

Пример с вращением

const force = new CANNON.Vec3(0, 0, 50);
const point = new CANNON.Vec3(0, 1, 0);

body.applyForce(force, point);

Тело начнёт вращаться вокруг оси X из-за ненулевого векторного произведения.


Постоянная сила во времени

Поскольку силы в Cannon.js обнуляются после каждого шага симуляции, постоянное воздействие реализуется через повторный вызов метода:

function upd ate() {
    body.applyForce(engineForce, enginePoint);
    world.step(1 / 60);
}

Именно таким образом моделируются:

  • тяга двигателя,
  • аэродинамическое сопротивление,
  • постоянное давление,
  • пользовательский ввод (движение персонажа).

Сравнение с другими методами

applyImpulse

Импульс мгновенно изменяет скорость тела и не зависит от времени шага.

body.applyImpulse(impulse, relativePoint);

Используется для:

  • выстрелов,
  • столкновений,
  • взрывов.

applyLocalForce

Работает аналогично applyForce, но сила задаётся в локальной системе координат тела.

body.applyLocalForce(localForce, localPoint);

Подходит для двигателей, закреплённых на вращающихся объектах.


Взаимодействие с массой

Тела с массой 0 (тип CANNON.Body.STATIC) не реагируют на силы. Для корректной работы метода необходимо, чтобы:

body.mass > 0

После изменения массы требуется вызвать:

body.updateMassProperties();

Пример: реализация тяги двигателя

const engineForce = new CANNON.Vec3(0, 0, 200);
const enginePoint = new CANNON.Vec3(0, -0.5, 0);

function update() {
    if (throttle) {
        body.applyLocalForce(engineForce, enginePoint);
    }

    world.step(1 / 60);
}

Особенности реализации:

  • Тяга прикладывается ниже центра масс.
  • Возникает наклон при ускорении.
  • Поведение становится более реалистичным за счёт комбинации линейного и углового ускорения.

Работа с демпфированием

Для контроля поведения тела используются коэффициенты:

body.linearDamping = 0.01;
body.angularDamping = 0.05;

Без демпфирования тело будет ускоряться бесконечно при постоянной силе.


Гравитация и пользовательские силы

Гравитация в Cannon.js также реализована как сила, автоматически добавляемая к телу:

world.gravity.se t(0, -9.82, 0);

Фактически на каждом шаге к телу добавляется:

F = m * g

Метод applyForce добавляет силу к уже существующим силам, включая гравитацию.


Производительность и численная устойчивость

Большие значения силы при малой массе могут привести к:

  • нестабильности симуляции,
  • «взрывному» поведению,
  • сильным осцилляциям.

Рекомендуется:

  • использовать адекватные масштабы мира (метры, килограммы),
  • соблюдать фиксированный шаг world.step,
  • избегать экстремальных значений.

Отладка

Текущие накопленные силы можно проверить через:

console.log(body.force);

Для визуализации удобно отображать направление силы вспомогательной стрелкой в графическом движке (например, Three.js).


Типовые сценарии использования

1. Движение персонажа

Плавное ускорение при нажатии клавиш.

2. Реактивная тяга

Постоянное воздействие, зависящее от ориентации.

3. Магнитное притяжение

Расчёт силы по формуле:

F = k * (1 / r²)

с последующим применением через applyForce.

4. Сопротивление среды

const drag = body.velocity.scale(-0.5);
body.applyForce(drag, new CANNON.Vec3());

Особенности системы координат

  • Вектор силы force задаётся в мировых координатах.
  • Точка relativePoint задаётся в локальной системе тела.
  • При необходимости преобразования используются методы:
body.pointToWorldFrame(localPoint, worldPoint);
body.vectorToWorldFrame(localVector, worldVector);

Внутреннее накопление сил

Внутри тела присутствуют поля:

body.force      // суммарная линейная сила
body.torque     // суммарный крутящий момент

После завершения шага интегрирования они автоматически обнуляются.


Поведение при сне (Sleep)

Если тело переведено в состояние сна:

body.sleep();

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

body.sleepSpeedLimit
body.sleepTimeLimit

Метод applyForce является фундаментальным инструментом динамического моделирования в Cannon.js, обеспечивая реалистичное поведение объектов за счёт точного учёта линейной и угловой динамики, взаимодействия с массой, инерцией и шагом симуляции.