Intersects и проверка пересечений

Работа с пересечениями — ключевой аспект векторной графики. В библиотеке Paper.js это реализовано через набор методов, позволяющих определять, пересекаются ли объекты, а также находить точные точки их пересечения. Основной акцент сделан на геометрическую точность и удобство API.


Базовый метод intersects()

Метод intersects() используется для быстрой проверки факта пересечения двух объектов.

var path1 = new Path.Circle({
    center: [100, 100],
    radius: 50
});

var path2 = new Path.Rectangle({
    point: [120, 80],
    size: [100, 100]
});

var result = path1.intersects(path2);
console.log(result); // true или false

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

  • Возвращает логическое значение (true или false)
  • Не предоставляет информацию о точках пересечения
  • Работает быстро, подходит для предварительных проверок

Получение точек пересечения: getIntersections()

Для более точного анализа используется метод getIntersections().

var intersections = path1.getIntersections(path2);

intersections.forEach(function(intersection) {
    console.log(intersection.point);
});

Что возвращается:

  • Массив объектов CurveLocation

  • Каждый объект содержит:

    • point — координаты пересечения
    • curve — кривая, на которой находится точка
    • offset — расстояние вдоль пути

Структура CurveLocation

Объекты пересечений содержат подробную информацию:

intersection.point     // Point
intersection.index     // индекс сегмента
intersection.offset    // положение на пути
intersection.curve     // кривая
intersection.path      // путь

Это позволяет не только определить координаты, но и понять контекст пересечения.


Пересечение одного пути с самим собой

Метод getIntersections() можно применять и для поиска самопересечений:

var path = new Path();
path.add([100, 100]);
path.add([200, 200]);
path.add([100, 200]);
path.add([200, 100]);

var selfIntersections = path.getIntersections(path);

Важно:

  • Возвращаются только реальные пересечения, а не совпадения соседних сегментов
  • Полезно при анализе сложных фигур и проверке корректности контуров

Работа с группами (Group)

Методы пересечений можно применять и к группам:

var group = new Group([path1, path2]);
var path3 = new Path.Circle({
    center: [150, 150],
    radius: 30
});

var intersections = group.getIntersections(path3);

Поведение:

  • Проверяются все дочерние элементы группы
  • Результат объединяется в один массив

Проверка пересечения с учётом трансформаций

Paper.js автоматически учитывает:

  • масштаб (scale)
  • поворот (rotate)
  • смещение (translate)
path2.rotate(45);
var result = path1.intersects(path2);

Нет необходимости вручную пересчитывать координаты — библиотека работает с глобальной системой координат.


Пересечения кривых Безье

Все пути в Paper.js состоят из кривых Безье. Методы пересечения работают именно на этом уровне.

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

  • высокая точность вычислений
  • возможны множественные точки пересечения
  • корректная обработка касательных пересечений

Оптимизация производительности

При работе с большим количеством объектов:

1. Предварительная проверка через bounds:

if (path1.bounds.intersects(path2.bounds)) {
    if (path1.intersects(path2)) {
        // более точная проверка
    }
}

2. Ограничение количества проверок:

  • использовать spatial partitioning (например, сетки)
  • проверять только потенциально близкие объекты

Касательные пересечения

Если объекты касаются, но не пересекаются “внутренне”:

var path1 = new Path.Circle([100, 100], 50);
var path2 = new Path.Circle([200, 100], 50);
  • intersects() вернёт true
  • getIntersections() вернёт одну точку

Пересечения и булевы операции

Методы пересечения тесно связаны с булевыми операциями:

var united = path1.unite(path2);
var intersected = path1.intersect(path2);
var subtracted = path1.subtract(path2);

Различия:

  • getIntersections() — анализ
  • intersect() — создание нового пути

Проверка попадания точки внутрь объекта

Хотя это не прямое пересечение, часто используется вместе:

var point = new Point(150, 150);
var contains = path1.contains(point);

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

1. Коллизии в играх

if (playerPath.intersects(enemyPath)) {
    // обработка столкновения
}

2. Выделение пересечений

intersections.forEach(function(i) {
    new Path.Circle({
        center: i.point,
        radius: 5,
        fillColor: 'red'
    });
});

3. Проверка корректности SVG

  • поиск самопересечений
  • выявление ошибок контуров

Точность и численные ошибки

При работе с пересечениями важно учитывать:

  • погрешности вычислений с плавающей точкой
  • близкие, но не совпадающие координаты

Рекомендация: использовать допуск (epsilon) при сравнении точек.


Ограничения метода

  • сложные пути могут требовать значительных вычислений
  • большое количество сегментов снижает производительность
  • пересечения учитывают только геометрию, не стиль (обводка, толщина)

Сравнение методов

Метод Назначение Возвращает
intersects() Быстрая проверка boolean
getIntersections() Точные точки Array
contains() Проверка точки boolean

Внутренний механизм

Paper.js:

  • разбивает пути на кривые Безье
  • вычисляет пересечения между кривыми
  • агрегирует результаты

Это делает API простым, скрывая сложную математику.


Итоговые принципы работы

  • быстрые проверки выполняются через intersects()
  • точный анализ — через getIntersections()
  • оптимизация достигается комбинированием методов
  • вся геометрия обрабатывается на уровне кривых

Работа с пересечениями в Paper.js позволяет строить сложные графические алгоритмы — от визуализации до физики взаимодействий.