Cylinder

В библиотеке Cannon.js цилиндр представляется классом CANNON.Cylinder, который позволяет создавать трёхмерные объекты с круглым основанием и возможностью вращения вокруг оси. Цилиндры часто применяются для моделирования колес, столбов, бочек и других объектов с круглой формой.

Конструктор CANNON.Cylinder

const cylinder = new CANNON.Cylinder(radiusTop, radiusBottom, height, numSegments);

Параметры:

  • radiusTop — радиус верхнего основания цилиндра.
  • radiusBottom — радиус нижнего основания. Если равен radiusTop, цилиндр получается правильным (равнобоким).
  • height — высота цилиндра.
  • numSegments — количество сегментов, на которые разбивается окружность основания. Чем больше значение, тем более гладкой будет поверхность цилиндра. Обычно используют 8–32 сегмента.

Пример создания цилиндра с одинаковыми основаниями:

const radius = 1;
const height = 2;
const segments = 16;
const cylinderShape = new CANNON.Cylinder(radius, radius, height, segments);

Ориентация цилиндра

По умолчанию ось цилиндра ориентирована вдоль локальной оси X. В большинстве случаев удобнее вращать цилиндр так, чтобы ось совпадала с мировой осью Y. Для этого применяется метод CANNON.Quaternion для задания ориентации:

const q = new CANNON.Quaternion();
q.setFromEuler(Math.PI / 2, 0, 0); // поворот вокруг оси X на 90 градусов
cylinderShape.transformAllPoints(new CANNON.Vec3(), q);
  • setFromEuler(alpha, beta, gamma) задаёт вращение через углы Эйлера (в радианах).
  • transformAllPoints(position, quaternion) применяет трансформацию к вершинам формы.

Добавление цилиндра в тело

Для того чтобы цилиндр взаимодействовал с физикой, его нужно добавить в объект CANNON.Body:

const body = new CANNON.Body({
    mass: 5, // масса тела
    position: new CANNON.Vec3(0, 5, 0), // начальная позиция
});

body.addShape(cylinderShape);
world.addBody(body);
  • mass — масса тела. Если указать 0, объект станет статичным.
  • position — начальная позиция центра масс.

Физические свойства цилиндра

Цилиндр имеет характерные моменты инерции, которые можно вычислить вручную или позволить Cannon.js вычислить их автоматически. Для идеального цилиндра формулы моменты инерции относительно осей X, Y, Z:

  • Для оси, проходящей через центр и параллельной основанию: ( I_x = I_z = m (3r^2 + h^2) )
  • Для оси, проходящей через центр и вдоль высоты: ( I_y = m r^2 )

CANNON.Body автоматически рассчитывает эти моменты при добавлении формы, но при сложной компоновке можно задать их вручную через inertia и invInertia.

Классические ошибки при работе с цилиндрами

  1. Неправильная ориентация: по умолчанию ось X может привести к неожиданным вращениям при применении силы. Решение — использовать Quaternion для выравнивания оси.
  2. Недостаточное количество сегментов: при малом numSegments цилиндр выглядит многогранником, а столкновения могут быть менее точными.
  3. Несовпадение визуальной и физической модели: если используется Three.js или Babylon.js для рендеринга, важно синхронизировать поворот и позицию визуального объекта с Cannon.js телом.

Совместное использование с другими формами

Цилиндры можно комбинировать с CANNON.Box, CANNON.Sphere и CANNON.ConvexPolyhedron для создания сложных конструкций. При этом порядок добавления форм и ориентация каждой формы определяет итоговое распределение массы и момент инерции.

const body = new CANNON.Body({ mass: 10 });
const box = new CANNON.Box(new CANNON.Vec3(1, 0.5, 1));
const cylinder = new CANNON.Cylinder(0.5, 0.5, 2, 16);

cylinder.transformAllPoints(new CANNON.Vec3(), new CANNON.Quaternion().setFromEuler(Math.PI / 2, 0, 0));

body.addShape(box, new CANNON.Vec3(0, 0, 0));
body.addShape(cylinder, new CANNON.Vec3(0, 1, 0));
world.addBody(body);
  • Первая форма задаёт базовую структуру, а вторая добавляется с оффсетом.
  • Vec3 задаёт смещение относительно центра массы тела.

Использование цилиндров в динамических симуляциях

Цилиндры применяются для имитации:

  • Колёс транспортных средств: с помощью HingeConstraint можно закреплять цилиндры-колёса к телу автомобиля.
  • Столбов и колонн: статические цилиндры создают препятствия и опоры.
  • Падающих объектов: цилиндры с равными основаниями демонстрируют естественные вращения и наклоны.

Для динамических объектов важно правильно рассчитывать массу и момент инерции, чтобы движения были реалистичными.

Оптимизация столкновений

Цилиндры — вычислительно сложные формы, особенно при большом числе сегментов. Для оптимизации можно использовать:

  • Уменьшение numSegments до минимально приемлемого уровня.
  • Замена сложного цилиндра на комбинацию CANNON.Box и CANNON.Sphere для приближённого коллайдера.
  • Кэширование Quaternion и Vec3 при массовом создании цилиндров для снижения нагрузки на GC.

Взаимодействие с другими объектами Cannon.js

Цилиндры корректно реагируют на:

  • Гравитацию: через свойство mass.
  • Силы и импульсы: метод applyForce позволяет задать силу в любой точке цилиндра.
  • Столкновения: коллизии обрабатываются автоматически, точность зависит от количества сегментов и ориентации.

Пример применения силы:

body.applyForce(new CANNON.Vec3(0, 100, 0), body.position);
  • Первый аргумент — сила в мировых координатах.
  • Второй — точка приложения относительно центра масс.

Итог

CANNON.Cylinder обеспечивает гибкое создание круглых объектов с точным физическим поведением. В сочетании с Body, Quaternion и другими формами можно моделировать сложные конструкции и динамические системы, от простых столбов до транспортных средств с вращающимися колёсами.