Позиция, ориентация и их инициализация

В библиотеке Cannon.js объекты мира представлены как экземпляры класса Body. Каждый Body обладает свойствами позиции и ориентации, которые определяют его положение и вращение в трехмерном пространстве.

  • Позиция (position) — вектор типа CANNON.Vec3, задающий координаты центра масс тела в пространстве:
const body = new CANNON.Body({
    mass: 5
});
body.position.set(1, 2, 3); // x=1, y=2, z=3
  • Ориентация (quaternion) — кватернион типа CANNON.Quaternion, который задает вращение тела относительно исходного положения. Кватернионы позволяют избежать проблем с углами Эйлера, таких как «замок Гимбала».
body.quaternion.setFromAxisAngle(new CANNON.Vec3(0,1,0), Math.PI / 2);

Здесь объект вращается вокруг оси Y на 90 градусов.

Инициализация позиции и ориентации при создании тела

Body принимает объект конфигурации, где можно задать начальные значения позиции и ориентации:

const shape = new CANNON.Box(new CANNON.Vec3(1,1,1));

const body = new CANNON.Body({
    mass: 10,
    position: new CANNON.Vec3(0,5,0),
    quaternion: new CANNON.Quaternion(0,0,0,1),
    shape: shape
});
  • mass — масса тела. Если mass = 0, тело становится статическим.
  • position — начальное положение.
  • quaternion — начальная ориентация.
  • shape — геометрическая форма, необходимая для расчета столкновений.

Манипулирование позицией

Позицию можно изменять напрямую или использовать методы вектора:

body.position.x += 1; // сдвиг по оси X
body.position.vadd(new CANNON.Vec3(0,1,0), body.position); // сложение векторов

Метод vadd позволяет аккуратно добавлять вектор к текущей позиции, избегая ошибок при работе с объектами.

Для перемещения объекта относительно его локальной системы координат используют комбинацию с кватернионом:

const localOffset = new CANNON.Vec3(1,0,0);
const worldOffset = body.quaternion.vmult(localOffset);
body.position.vadd(worldOffset, body.position);

Здесь vmult преобразует локальный вектор в мировую систему координат.

Манипулирование ориентацией

Изменение ориентации тела возможно через кватернионы или углы Эйлера (с последующим преобразованием):

const q = new CANNON.Quaternion();
q.setFromEuler(Math.PI/4, 0, 0, "XYZ"); // вращение 45° вокруг X
body.quaternion = q;

Для постепенного вращения применяют методы mult и normalize:

const rotation = new CANNON.Quaternion();
rotation.setFromAxisAngle(new CANNON.Vec3(0,1,0), 0.1);
body.quaternion = body.quaternion.mult(rotation);
body.quaternion.normalize();

Нормализация необходима для поддержания корректной кватернионной структуры после последовательных умножений.

Синхронизация позиции и ориентации с физическим миром

Каждый шаг симуляции обновляет положение и ориентацию тела на основе физики:

const world = new CANNON.World();
world.addBody(body);

function stepSimulation(dt) {
    world.step(dt);
    console.log(body.position, body.quaternion);
}
  • world.step(dt) рассчитывает новую позицию и ориентацию с учетом сил, столкновений и импульсов.
  • После шага симуляции свойства position и quaternion всегда отражают текущее состояние тела в мире.

Использование ориентации для сложных форм

Для тел со сложной геометрией ориентация критически важна, так как коллизии рассчитываются относительно локальной системы координат формы:

const boxShape = new CANNON.Box(new CANNON.Vec3(1,2,0.5));
const boxBody = new CANNON.Body({
    mass: 5,
    shape: boxShape
});
boxBody.quaternion.setFromEuler(0, Math.PI/4, 0); // поворот вокруг Y

Вращение влияет на точки соприкосновения и направление силы тяжести относительно формы.

Работа с привязками и позиционными смещениями

Для создания составных объектов или привязки тел используют смещения позиции и ориентации относительно родителя:

const parent = new CANNON.Body({ mass: 0 });
const child = new CANNON.Body({ mass: 1 });

child.position.set(0,2,0); 
parent.addShape(child.shapes[0], new CANNON.Vec3(0,2,0));
  • Второй параметр addShape задает смещение формы относительно центра родительского тела.
  • Это позволяет моделировать сложные конструкции, такие как механизмы или транспортные средства.

Практические советы

  • Всегда инициализировать кватернион через setFromEuler или setFromAxisAngle, а не напрямую изменять компоненты, чтобы избежать некорректного вращения.
  • Для динамических тел position и quaternion лучше изменять через физические силы или импульсы, чтобы симуляция оставалась реалистичной.
  • Смешение локальных и мировых координат требует внимательности: vmult помогает правильно трансформировать векторы между системами координат.

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