Импульс в физике — это мгновенное изменение количества движения тела. В контексте движка Cannon.js импульс используется для резкого изменения линейной и угловой скорости тела без непосредственного задания новой скорости вручную.
В отличие от постоянной силы (applyForce), которая
действует в течение временного шага симуляции, импульс применяется
однократно и немедленно изменяет состояние объекта. Это особенно важно
при моделировании:
Математически импульс определяется как:
[ J = F t]
где:
J — импульс,F — сила,Δt — интервал времени действия силы.В физическом движке импульс сразу изменяет скорость тела:
[ v = v + ]
где m — масса тела.
У каждого динамического тела (CANNON.Body) доступен
метод:
body.applyImpulse(impulse, worldPoint);
CANNON.Vec3, вектор
импульса.Импульс задаётся в ньютон-секундах (N·s), а точка приложения определяет, будет ли тело только двигаться или ещё и вращаться.
Если импульс приложен строго к центру масс, тело изменяет только линейную скорость без вращения.
const impulse = new CANNON.Vec3(10, 0, 0);
body.applyImpulse(impulse, body.position);
В этом случае:
Такой подход используется при:
Если точка приложения не совпадает с центром масс, возникает крутящий момент.
const impulse = new CANNON.Vec3(0, 0, 20);
const contactPoint = new CANNON.Vec3(
body.position.x,
body.position.y + 1,
body.position.z
);
body.applyImpulse(impulse, contactPoint);
Результат:
Вращение вычисляется через векторное произведение:
[ = r J]
где:
r — вектор от центра масс до точки приложения,J — импульс.Чем дальше точка приложения от центра, тем сильнее вращение.
Масса напрямую влияет на изменение скорости:
[ v = ]
Пример:
const lightBody = new CANNON.Body({ mass: 1 });
const heavyBody = new CANNON.Body({ mass: 100 });
const impulse = new CANNON.Vec3(50, 0, 0);
lightBody.applyImpulse(impulse, lightBody.position);
heavyBody.applyImpulse(impulse, heavyBody.position);
Лёгкое тело резко ускорится, тяжёлое — едва заметно.
| Характеристика | applyImpulse | applyForce |
|---|---|---|
| Временная природа | Мгновенно | В течение шага |
| Изменение скорости | Немедленно | Постепенно |
| Подходит для | Ударов, выстрелов | Двигателей, тяги |
applyForce аккумулируется и интегрируется в течение шага
симуляции. applyImpulse изменяет скорость немедленно, минуя
интеграцию силы во времени.
Метод applyImpulse принимает точку в мировых
координатах. Если требуется задать импульс в локальной системе
координат тела, необходимо выполнить преобразование:
const localPoint = new CANNON.Vec3(0, 1, 0);
const worldPoint = body.pointToWorldFrame(localPoint);
body.applyImpulse(new CANNON.Vec3(0, 0, 10), worldPoint);
Без правильного преобразования импульс будет приложен в неверной точке, что приведёт к некорректному вращению.
Во время столкновения движок автоматически рассчитывает контактные импульсы. Однако возможно программное вмешательство, например, при реализации:
Пример усиленного отскока:
world.addEventListener("postStep", () => {
if (collisionDetected) {
const boost = new CANNON.Vec3(0, 20, 0);
body.applyImpulse(boost, body.position);
}
});
Импульс изменяет уже вычисленную скоростью после стандартной обработки контакта.
Импульс — оптимальный способ реализовать прыжок персонажа:
function jump() {
const jumpImpulse = new CANNON.Vec3(0, 5 * body.mass, 0);
body.applyImpulse(jumpImpulse, body.position);
}
Умножение на массу обеспечивает одинаковую высоту прыжка для тел разной массы.
При приложении вне центра масс изменяется свойство:
body.angularVelocity
Для контроля вращения после импульса может потребоваться ограничение:
body.angularDamping = 0.5;
Высокое демпфирование снижает скорость вращения со временем.
Если тело находится в состоянии сна (sleeping), вызов
applyImpulse автоматически пробуждает его. Это позволяет
корректно взаимодействовать с неподвижными объектами.
body.sleep();
body.applyImpulse(new CANNON.Vec3(10, 0, 0), body.position);
После применения импульса тело активируется.
function shoot() {
const shootDirection = new CANNON.Vec3(0, 0, -1);
const power = 50;
const impulse = shootDirection.scale(power);
projectile.applyImpulse(impulse, projectile.position);
// отдача
const recoil = shootDirection.scale(-power * 0.2);
playerBody.applyImpulse(recoil, playerBody.position);
}
Здесь:
Так достигается реалистичная физическая отдача.
Слишком большие импульсы могут привести к:
Рекомендуется:
world.step,continuous collision detection при
необходимости.При наличии ограничений (HingeConstraint,
PointToPointConstraint) импульс может приводить к:
Импульс действует до расчёта ограничений на текущем шаге, поэтому итоговое движение корректируется системой ограничений.
function explode(center, radius, strength) {
world.bodies.forEach(body => {
const distance = body.position.distanceTo(center);
if (distance < radius) {
const direction = body.position.vsub(center);
direction.normalize();
const force = strength * (1 - distance / radius);
const impulse = direction.scale(force);
body.applyImpulse(impulse, body.position);
}
});
}
Особенности:
После применения импульса скорость можно ограничить:
const maxSpeed = 20;
if (body.velocity.length() > maxSpeed) {
body.velocity.scale(
maxSpeed / body.velocity.length(),
body.velocity
);
}
Это предотвращает чрезмерное ускорение.
Внутри движка импульс:
Изменяет линейную скорость:
velocity += impulse * invMassВычисляет момент:
torque = r x impulseИзменяет угловую скорость через инерционный тензор.
Таким образом, applyImpulse — это прямое вмешательство в
кинематическое состояние тела, минуя накопление сил.
Импульс предпочтителен при моделировании:
Для длительного воздействия (двигатели, тяга, ветер) следует использовать силы.
Метод applyImpulse в Cannon.js является фундаментальным
инструментом для создания реалистичных мгновенных взаимодействий в
физической симуляции. Корректное понимание точки приложения, массы,
инерции и масштаба импульса позволяет строить устойчивые и предсказуемые
физические модели любой сложности.