В физическом моделировании объектов важным аспектом является
инерция, которая определяет сопротивление тела
изменению своей скорости при приложении силы. В библиотеке
Ammo.js, являющейся JavaScript-портом популярного
движка Bullet Physics, для расчёта локальной инерции используется метод
calculateLocalInertia, который вычисляет
тензор инерции для тел с различными формами.
Локальная инерция — это матрица, отражающая распределение массы объекта относительно его локальной системы координат. Она отличается от глобальной инерции тем, что всегда вычисляется в системе координат самого объекта, что упрощает расчёт динамики при вращении и взаимодействии с внешними силами.
Тензор инерции (btVector3 в Ammo.js)
задаёт моменты инерции по трем основным осям:
Для симметричных объектов (куб, сфера) тензор имеет одинаковые значения для осей, тогда как для асимметричных тел значения различаются.
shape.calculateLocalInertia(mass, inertia);
Параметры:
shape — объект формы (btBoxShape,
btSphereShape, btCylinderShape,
btConvexHullShape и т.д.).mass — масса тела. Для статических объектов
(mass = 0) расчёт инерции не производится, так как
статические тела не вращаются.inertia — объект типа Ammo.btVector3, в
который будет записан результат.Метод не возвращает значение, а заполняет переданный
объект inertia.
// Создание формы куба
const halfExtents = new Ammo.btVector3(1, 1, 1);
const boxShape = new Ammo.btBoxShape(halfExtents);
// Масса тела
const mass = 2;
// Вектор для хранения локальной инерции
const localInertia = new Ammo.btVector3(0, 0, 0);
// Расчёт локальной инерции
boxShape.calculateLocalInertia(mass, localInertia);
console.log("Локальная инерция по осям:", localInertia.x(), localInertia.y(), localInertia.z());
Для куба с равными сторонами моменты инерции по всем осям будут одинаковыми, что соответствует формуле классической механики:
[ I_x = I_y = I_z = m (a^2 + b^2)]
где a и b — размеры куба по соответствующим
осям.
Сфера (btSphereShape) Для сферы
локальная инерция рассчитывается одинаково по всем осям, по формуле:
[ I = m r^2]
Цилиндр (btCylinderShape) Инерция
зависит от направления цилиндра. Для вертикального цилиндра моменты
вокруг осей X и Z равны, а Y отличается.
Выпуклый многоугольник
(btConvexHullShape) Расчёт выполняется численно.
Ammo.js интегрирует распределение массы по всем вершинам, учитывая
асимметрию формы.
После вычисления локальной инерции её необходимо передать при создании rigid body:
const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(0, 5, 0));
const motionState = new Ammo.btDefaultMotionState(transform);
const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, boxShape, localInertia);
const body = new Ammo.btRigidBody(rbInfo);
Использование правильной локальной инерции обеспечивает реалистичное поведение объекта при вращении и столкновениях. Без корректного расчёта тело может вести себя нестабильно или вращаться неадекватно.
calculateLocalInertia можно пропускать.btVector3, чтобы избежать накопления ошибок.// Куб + сфера
const box = new Ammo.btBoxShape(new Ammo.btVector3(1, 1, 1));
const sphere = new Ammo.btSphereShape(0.5);
const massBox = 1;
const massSphere = 0.5;
const inertiaBox = new Ammo.btVector3(0, 0, 0);
const inertiaSphere = new Ammo.btVector3(0, 0, 0);
box.calculateLocalInertia(massBox, inertiaBox);
sphere.calculateLocalInertia(massSphere, inertiaSphere);
// Для комбинированного тела моменты суммируются по осям
const combinedInertia = new Ammo.btVector3(
inertiaBox.x() + inertiaSphere.x(),
inertiaBox.y() + inertiaSphere.y(),
inertiaBox.z() + inertiaSphere.z()
);
Этот подход позволяет строить сложные конструкции с реалистичной динамикой вращения.
Локальная инерция через calculateLocalInertia является
ключевым инструментом для создания реалистичных физически корректных
объектов в Ammo.js. Понимание того, как форма и масса влияют на тензор
инерции, критично для точного моделирования динамических систем.