Пересечения и коллизии

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


Координаты и границы объектов

Каждый элемент SVG в SVG.js обладает методами .bbox() и .rbox(), возвращающими информацию о позиционировании и размерах объекта:

  • .bbox() – возвращает ограничивающий прямоугольник (bounding box) элемента в локальных координатах. Формат объекта:
{
  x: <координата X>,
  y: <координата Y>,
  width: <ширина>,
  height: <высота>
}
  • .rbox(parent) – возвращает bounding box относительно указанного родителя, что удобно для вычислений пересечений в сложных иерархиях.

Используя эти методы, можно определить потенциальное пересечение двух объектов, проверяя пересечение их bounding box:

function isColliding(a, b) {
  const boxA = a.bbox();
  const boxB = b.bbox();

  return !(
    boxA.x + boxA.width < boxB.x ||
    boxA.x > boxB.x + boxB.width ||
    boxA.y + boxA.height < boxB.y ||
    boxA.y > boxB.y + boxB.height
  );
}

Эта проверка работает для прямоугольных областей, что подходит для большинства практических случаев, включая группы объектов и простые фигуры.


Работа с кривыми и сложными формами

Для фигур с кривыми (например, path) простая проверка bounding box может быть слишком грубой. В этом случае применяется поэлементное сравнение координат или использование методов .array() и .length():

const pathA = draw.path('M10 10L50 50');
const pathB = draw.path('M30 30L70 70');

const pointsA = pathA.array().toArray();
const pointsB = pathB.array().toArray();

На основе массивов точек можно реализовать алгоритмы проверки пересечений:

  1. Пересечение отрезков – проверка каждой пары сегментов из двух paths.
  2. Алгоритмы полигона – например, использование метода ray casting для определения попадания точек одного объекта в границы другого.

Коллизии и события

SVG.js позволяет не только вычислять пересечения программно, но и связывать их с событиями DOM. Это дает возможность динамически реагировать на столкновения при анимациях или интерактивных приложениях:

rectA.on('dragmove', function() {
  if (isColliding(rectA, rectB)) {
    rectA.fill({ color: 'red' });
  } else {
    rectA.fill({ color: 'blue' });
  }
});

Ключевые моменты:

  • .bbox() и .rbox() – базовые инструменты для вычисления пересечений.
  • Для сложных форм требуется разложение пути на сегменты и проверка точек на вхождение в другую фигуру.
  • События dragmove, mousemove и animation позволяют визуально отслеживать коллизии в реальном времени.

Использование масок и пересечений

SVG.js поддерживает работу с clipPath и mask, что позволяет вычислять пересечения графически. Это может быть особенно полезно для визуальных эффектов и интерактивных элементов:

const circle = draw.circle(100).move(50, 50);
const rect = draw.rect(120, 80).move(30, 30);

const clip = draw.clip().add(rect);
circle.clipWith(clip);

В этом примере область пересечения circle и rect визуализируется через clip, а программная проверка пересечения может быть дополнительно реализована через bbox().


Оптимизация вычислений

Для большого числа элементов важно минимизировать количество проверок пересечений. Основные методы оптимизации:

  1. Иерархическая проверка – сначала проверка bounding box, затем точная проверка.
  2. Пространственное деление – использование сетки или квадродерева для ограничения проверки только ближайших объектов.
  3. Кэширование размеров и координат – особенно при анимациях, чтобы не вызывать .bbox() каждый кадр без необходимости.

Практические сценарии

  • Игровые механики: столкновения персонажей и объектов.
  • Интерактивные схемы: определение пересечения draggable элементов с зонами.
  • Графические редакторы: точная проверка наложений фигур при трансформациях.
  • Анимации: динамическая смена цвета или состояния при контакте объектов.

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