Комбинирование упругости при столкновении

Oimo.js — это легковесная физическая библиотека для JavaScript, ориентированная на симуляцию твердых тел с использованием метода физики жестких тел. Одним из ключевых параметров, влияющих на реализм столкновений, является упругость (restitution). Упругость определяет, насколько сильно объекты отскакивают друг от друга после столкновения. Значение может находиться в диапазоне от 0 до 1:

  • 0 — полностью неупругое столкновение, энергия практически полностью поглощается, объекты «слипаются» или останавливаются.
  • 1 — идеально упругое столкновение, энергия сохраняется, объекты отскакивают с максимальной скоростью.

В Oimo.js параметр упругости задается через свойство restitution при создании формы (ShapeConfig) или тела (RigidBodyConfig).

let boxConfig = {
    size: [1, 1, 1],
    move: true,
    density: 1,
    restitution: 0.8
};

Комбинирование упругости при столкновении

Когда два тела сталкиваются, их индивидуальные значения restitution не используются напрямую. Oimo.js применяет комбинированное значение упругости, которое зависит от выбранного метода комбинирования. Библиотека поддерживает стандартную формулу для комбинирования:

[ e_ = ]

где e_1 и e_2 — упругости сталкивающихся объектов. Этот метод позволяет получить реалистичное поведение: если один объект полностью упругий, а другой абсолютно неупругий, общий отскок будет умеренным, а не максимальным.

Пример создания двух тел с разной упругостью и наблюдение комбинированного эффекта:

let sphereConfig = {
    radius: 0.5,
    move: true,
    restitution: 0.9
};

let cubeConfig = {
    size: [1, 1, 1],
    move: true,
    restitution: 0.2
};

let sphere = new OIMO.Body({ type: 'sphere', config: sphereConfig });
let cube = new OIMO.Body({ type: 'box', config: cubeConfig });

world.addBody(sphere);
world.addBody(cube);

При столкновении этих тел Oimo.js автоматически рассчитает комбинированную упругость примерно равную √(0.9*0.2) ≈ 0.42, что отражает промежуточный отскок.

Настройка метода комбинирования

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

let contact = world.createContact(sphere, cube);
contact.restitutionCombineMode = OIMO.Contact.BOUNCE_GEOMETRIC;

Доступные методы комбинирования:

  • GEOMETRIC — стандартное геометрическое среднее.
  • MINIMUM — минимальное значение упругости из двух объектов.
  • MAXIMUM — максимальное значение упругости из двух объектов.
  • ARITHMETIC — среднее арифметическое двух значений.

Каждый метод имеет свое применение: геометрическое среднее подходит для реалистичной физики, минимальное — для создания «тяжелых» контактов, максимальное — для сверхупругих поверхностей, а арифметическое — для упрощенных моделей, где нужен линейный эффект.

Влияние массы и скорости на столкновение

Упругость взаимодействует с массой и скоростью объектов. Важно учитывать, что комбинированная упругость не изменяет закон сохранения импульса. Скорость отскока вычисляется как:

[ v_ = -e_ v_]

где v_relative — скорость сближения вдоль нормали столкновения. Масса объектов влияет на распределение импульса между ними, что в сочетании с упругостью формирует реалистичную динамику.

let massSphere = 2; // кг
let massCube = 5;   // кг

sphere.setMass(massSphere);
cube.setMass(massCube);

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

Практические рекомендации

  • Для реалистичных симуляций твердых тел лучше использовать геометрическое среднее.
  • Для материалов с сильно различающимися свойствами (например, металл и резина) экспериментировать с MINIMUM или MAXIMUM для визуального эффекта.
  • Следить за тем, чтобы значения restitution не превышали 1, иначе объекты будут «летать» после столкновения.
  • При симуляции множества объектов учитывать, что комбинированная упругость влияет на стабильность системы: слишком высокие значения могут привести к нежелательной нестабильности и дрожанию.

Примеры комплексных столкновений

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

let groundConfig = { size: [10, 1, 10], move: false, restitution: 0.3 };
let ballConfig = { radius: 0.5, move: true, restitution: 0.7 };
let rubberCubeConfig = { size: [1, 1, 1], move: true, restitution: 0.9 };

let ground = new OIMO.Body({ type: 'box', config: groundConfig });
let ball = new OIMO.Body({ type: 'sphere', config: ballConfig });
let rubberCube = new OIMO.Body({ type: 'box', config: rubberCubeConfig });

world.addBody(ground);
world.addBody(ball);
world.addBody(rubberCube);

При падении шара на землю отскок будет умеренным (√(0.7*0.3) ≈ 0.46), а резиновый куб, падая на шар, создаст более заметный отскок (√(0.9*0.7) ≈ 0.79).

Итоговый подход

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