GSSolver: параметры iterations и tolerance

GSSolver является одним из основных решателей системы ограничений в физическом движке Cannon.js. Он используется для вычисления сил и импульсов, которые обеспечивают выполнение различных ограничений между телами, таких как столкновения, соединения (constraints) и фиксации. Понимание параметров iterations и tolerance критично для точного моделирования физических взаимодействий и оптимизации производительности.


Основные принципы работы GSSolver

GSSolver реализует метод Gauss-Seidel для решения системы линейных ограничений. Принцип заключается в итеративном приближении решения системы уравнений вида:

A * x = b

где:

  • A — матрица ограничений,
  • x — вектор неизвестных (импульсы, силы),
  • b — вектор целевых изменений (смещения, скорости).

Итерационный метод позволяет постепенно уточнять значения импульсов до тех пор, пока система не достигнет допустимой точности. В этом процессе наибольшее влияние оказывают два параметра: iterations и tolerance.


Параметр iterations

iterations определяет максимальное количество итераций, выполняемых для решения системы ограничений за один шаг симуляции. Его влияние проявляется в следующих аспектах:

  1. Точность решения Чем больше число итераций, тем ближе результат к идеальному решению ограничений. Недостаток итераций может приводить к:

    • «проваливанию» тел через препятствия,
    • нестабильности соединений и рвущимся конструкциям,
    • заметным физическим артефактам при сложных взаимодействиях.
  2. Производительность Каждая итерация требует вычисления для всех ограничений. С увеличением iterations растёт нагрузка на CPU. Оптимальное значение зависит от сложности сцены:

    • для простых сцен достаточно 5–10 итераций,
    • для сложных механических конструкций или стеков объектов может потребоваться 20–50 итераций.

Пример настройки:

const solver = new CANNON.GSSolver();
solver.iterations = 20;

Параметр tolerance

tolerance задаёт порог погрешности, при котором итерационный процесс считается завершённым. Если изменения в импульсах между итерациями становятся меньше tolerance, решатель останавливается раньше достижения максимального числа итераций.

Особенности tolerance:

  1. Контроль точности

    • Низкое значение (например, 1e-7) повышает точность, но увеличивает время расчёта.
    • Высокое значение (например, 1e-3) ускоряет симуляцию, но может допускать заметные отклонения в поведении тел.
  2. Баланс производительности и стабильности Вместо увеличения числа итераций для повышения точности часто эффективнее уменьшить tolerance, что позволяет решателю адаптивно завершать вычисления при достижении достаточной точности.

Пример настройки:

solver.tolerance = 1e-6;

Взаимодействие iterations и tolerance

Эти параметры взаимосвязаны. iterations задаёт верхнюю границу работы решателя, а tolerance — условие досрочного завершения:

  • Слишком мало итераций при низкой tolerance Решатель не успевает достичь требуемой точности → нестабильные ограничения.

  • Много итераций при высокой tolerance Решатель тратит ресурсы впустую, так как точность ограничений уже достаточна для заданного порога.

Оптимальная стратегия:

  • Установить iterations в разумный диапазон для сцены (например, 10–20 для большинства игровых симуляций).
  • Настроить tolerance так, чтобы решатель завершал работу при достижении нужной точности без лишних вычислений.

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

  1. Для стеков объектов и сложных механических систем:

    • iterations: 20–40
    • tolerance: 1e-6 – 1e-7
  2. Для простых симуляций с ограниченным количеством тел:

    • iterations: 5–15
    • tolerance: 1e-5 – 1e-4
  3. Для реализации соединений типа Hinges или Springs:

    • iterations: 10–30
    • tolerance: 1e-6
  4. В случае нестабильных тел, «проваливания» через поверхность или дрожания объектов — следует увеличивать iterations и уменьшать tolerance, а также проверять правильность массы и формы тел.


Пример использования GSSolver в сцене Cannon.js

const world = new CANNON.World();
world.gravity.set(0, -9.82, 0);

// Настройка GSSolver
const solver = new CANNON.GSSolver();
solver.iterations = 20;
solver.tolerance = 1e-6;

world.solver = solver;

// Создание тел
const ground = new CANNON.Body({ mass: 0 });
ground.addShape(new CANNON.Plane());
world.addBody(ground);

const box = new CANNON.Body({ mass: 1 });
box.addShape(new CANNON.Box(new CANNON.Vec3(1, 1, 1)));
box.position.set(0, 10, 0);
world.addBody(box);

// Симуляция
function simulate(timeStep) {
    world.step(timeStep);
}

В этом примере решатель с 20 итерациями и tolerance 1e-6 обеспечивает стабильное взаимодействие между объектами и предотвращает проникновение тел сквозь плоскость.


Вывод

Параметры iterations и tolerance в GSSolver отвечают за точность и эффективность расчёта ограничений. Баланс между ними позволяет контролировать производительность и стабильность симуляции. Для разных типов сцен и взаимодействий рекомендуется адаптировать их значения, ориентируясь на сложность системы, желаемую физическую точность и нагрузку на вычислительные ресурсы.