Применение пружин к колёсным подвескам

Cannon.js — это физический движок на JavaScript, который предоставляет возможность моделировать динамику твёрдых тел, столкновения, трение и силы. Для моделирования колёсных подвесок ключевым инструментом являются пружины и ограничения, которые позволяют имитировать амортизацию и подвижность колёс относительно кузова.


Создание физического мира

Первый шаг — создание мира с настройкой гравитации и параметров интеграции:

const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;
  • gravity задаёт направление и силу гравитации.
  • broadphase определяет алгоритм, который ускоряет проверку столкновений.
  • solver.iterations влияет на точность расчёта сил и ограничений.

Определение кузова и колёс

Кузов обычно моделируется как CANNON.Body с формой Box или ConvexPolyhedron. Колёса создаются как Sphere или цилиндр:

const chassisShape = new CANNON.Box(new CANNON.Vec3(1, 0.5, 2));
const chassisBody = new CANNON.Body({ mass: 1500 });
chassisBody.addShape(chassisShape);

const wheelShape = new CANNON.Sphere(0.5);
const wheelBody = new CANNON.Body({ mass: 20 });
wheelBody.addShape(wheelShape);
  • Масса кузова и колёс критична для правильной амортизации.
  • Размеры форм влияют на поведение при столкновениях и опоре на поверхность.

Настройка пружин и подвески

Для реализации подвески применяются Spring и DistanceConstraint. Основная идея — соединить колёса с кузовом через пружину, которая может растягиваться и сжиматься.

const suspension = new CANNON.Spring(chassisBody, wheelBody, {
    localAnchorA: new CANNON.Vec3(1, 0, 1), // точка крепления на кузове
    localAnchorB: new CANNON.Vec3(0, 0, 0), // центр колеса
    restLength: 0.5,
    stiffness: 200,
    damping: 10
});
  • localAnchorA и localAnchorB определяют точки прикрепления пружины.
  • restLength — естественная длина пружины.
  • stiffness — жёсткость; чем выше значение, тем более твёрдая подвеска.
  • damping — коэффициент демпфирования, сглаживающий колебания.

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

world.addEventListener('postStep', () => {
    suspension.applyForce();
});

Реализация подвески с ограничениями

Для ограничения движения колёс по вертикали можно использовать CANNON.DistanceConstraint или CANNON.LockConstraint для имитации фиксированных осей:

const wheelConstraint = new CANNON.DistanceConstraint(chassisBody, wheelBody, 0.5);
world.addConstraint(wheelConstraint);
  • Это предотвращает чрезмерное растяжение пружины.
  • Позволяет точнее моделировать физику подвески при ускорении и торможении.

Применение нескольких колёс

Для четырёхколёсного транспортного средства создаются отдельные пружины для каждого колеса:

const wheels = [];
const suspensions = [];
const positions = [
    new CANNON.Vec3(1, 0, 1),
    new CANNON.Vec3(-1, 0, 1),
    new CANNON.Vec3(1, 0, -1),
    new CANNON.Vec3(-1, 0, -1)
];

positions.forEach(pos => {
    const wheel = new CANNON.Body({ mass: 20 });
    wheel.addShape(new CANNON.Sphere(0.5));
    wheel.position.copy(chassisBody.position.vadd(pos));
    wheels.push(wheel);
    world.addBody(wheel);

    const spring = new CANNON.Spring(chassisBody, wheel, {
        localAnchorA: pos,
        localAnchorB: new CANNON.Vec3(0, 0, 0),
        restLength: 0.5,
        stiffness: 200,
        damping: 10
    });
    suspensions.push(spring);
});

world.addEventListener('postStep', () => {
    suspensions.forEach(s => s.applyForce());
});
  • Каждое колесо имеет свою индивидуальную пружину, что позволяет им независимо реагировать на неровности.
  • Настройка stiffness и damping для каждого колеса позволяет моделировать различные типы подвески: мягкую, спортивную или грузовую.

Настройка демпфирования и жёсткости

Сочетание stiffness и damping критично для реалистичности:

  • Слишком высокая жёсткость — подвеска становится жесткой, кузов почти не поднимается при неровностях.
  • Слишком низкая жёсткость — колёса могут пробивать кузов или «проседать» слишком глубоко.
  • Слишком высокий damping — колёса медленно возвращаются в исходное положение, движения кажутся «тяжёлыми».
  • Слишком низкий damping — колёса будут раскачиваться, создавая эффект «качелей».

Дополнительные оптимизации

  1. Масса колеса и кузова должны соответствовать реалистичному соотношению, иначе пружины будут вести себя неестественно.
  2. Частота шагов симуляции (world.step(dt)) влияет на стабильность: рекомендуется dt около 1/60.
  3. Проверка столкновений колёс с землёй через contactMaterial улучшает сцепление и предотвращает проваливание.
  4. Вектор силы пружины всегда направлен вдоль линии соединения точек крепления.

Интеграция с визуализацией

Для отображения колёс и кузова используется Three.js или любой другой движок. Позиции объектов синхронизируются после шага физики:

world.step(1/60);
meshChassis.position.copy(chassisBody.position);
meshChassis.quaternion.copy(chassisBody.quaternion);

wheels.forEach((wheel, i) => {
    meshWheels[i].position.copy(wheel.position);
    meshWheels[i].quaternion.copy(wheel.quaternion);
});
  • Это позволяет визуально отслеживать работу пружин и реакции подвески на неровности.

Cannon.js позволяет строить сложные модели колёсных подвесок с индивидуальными пружинами для каждого колеса, контролировать демпфирование, жёсткость и ограничения. Комбинация Spring, DistanceConstraint и точной настройки массы и параметров мира обеспечивает реалистичное поведение транспортного средства в 3D-среде.