Intersect и пересечение

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


Пересечение линий и кривых

В Paper.js для нахождения пересечения используются методы getIntersections и intersect объектов Path.

Пример нахождения пересечения двух линий:

var line1 = new Path.Line({
    from: [50, 50],
    to: [200, 200],
    strokeColor: 'red'
});

var line2 = new Path.Line({
    from: [50, 200],
    to: [200, 50],
    strokeColor: 'blue'
});

var intersections = line1.getIntersections(line2);
intersections.forEach(function(intersect) {
    var point = intersect.point;
    new Path.Circle({
        center: point,
        radius: 5,
        fillColor: 'green'
    });
});
  • getIntersections возвращает массив объектов Intersection, каждый из которых содержит:

    • point — координаты точки пересечения;
    • parameter — положение точки на пути (от 0 до 1);
    • segment — сегмент, на котором произошло пересечение.

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

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

Пересечение сложных объектов

Для сложных форм, таких как многоугольники или кривые, пересечение можно выполнить через метод PathItem.intersect(path):

var circle = new Path.Circle({
    center: [150, 150],
    radius: 100,
    strokeColor: 'orange'
});

var rectangle = new Path.Rectangle({
    point: [100, 100],
    size: [150, 150],
    strokeColor: 'purple'
});

var result = circle.intersect(rectangle);
result.strokeColor = 'green';

Особенности работы:

  • Метод intersect возвращает новый объект PathItem, представляющий геометрию пересечения.
  • Если объектов нет пересечения, возвращается пустой Path.
  • Можно использовать комбинации unite, subtract и exclude для сложных булевых операций над формами.

Определение пересечения по точке

Иногда необходимо проверить, пересекаются ли объекты без построения нового пути. Для этого используется метод hitTest:

var path1 = new Path.Circle([150, 150], 50);
var path2 = new Path.Circle([180, 150], 50);

var hit = path1.hitTest(path2.bounds.center);
if(hit){
    console.log('Пересечение есть');
}

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

  • hitTest возвращает объект HitResult или null.
  • Можно задавать точность поиска через параметр tolerance.
  • Подходит для интерактивных приложений, где важно обнаружить контакт объектов.

Массив пересечений для сложных объектов

Paper.js позволяет сразу получить все точки пересечения между сложными объектами:

var star = new Path.Star({
    center: [200, 200],
    points: 5,
    radius1: 50,
    radius2: 100,
    strokeColor: 'blue'
});

var circle = new Path.Circle({
    center: [200, 200],
    radius: 70,
    strokeColor: 'red'
});

var intersections = star.getIntersections(circle);
intersections.forEach(function(i) {
    new Path.Circle({
        center: i.point,
        radius: 4,
        fillColor: 'black'
    });
});
  • Метод getIntersections работает для любого типа PathItem, включая CompoundPath.
  • Для сложных фигур полезно визуализировать точки пересечения для отладки и анализа.

Пересечение с использованием Curve

Каждая кривая в Paper.js представлена объектом Curve, у которого есть метод getIntersections(curve), позволяющий получить более точное пересечение:

var curve1 = new Path().add(new Point(50, 50)).cubicCurveTo(new Point(100, 150), new Point(150, 50), new Point(200, 150));
var curve2 = new Path().add(new Point(50, 150)).cubicCurveTo(new Point(100, 50), new Point(150, 150), new Point(200, 50));

var intersections = [];
curve1.curves.forEach(c1 => {
    curve2.curves.forEach(c2 => {
        intersections.push(...c1.getIntersections(c2));
    });
});
  • Использование Curve позволяет точнее контролировать позиции пересечений на кривых Безье.
  • Для численных вычислений используются методы разбиения кривой на отрезки и поиска точек пересечения на этих сегментах.

Практические советы

  • Для динамических анимаций пересечение лучше рассчитывать на основе сегментов кривых (Curve), чтобы избежать ошибок округления.
  • При работе с большими числами объектов следует минимизировать количество проверок через hitTest или предварительное ограничение области через bounds.intersects().
  • Булевы операции (intersect, unite, subtract, exclude) создают новые объекты, старые остаются неизменными. Для оптимизации можно объединять пути через PathItem.flatten() перед пересечением.

Использование Intersect и пересечений в Paper.js открывает возможности для создания сложных графических алгоритмов, от генеративного дизайна до интерактивных визуализаций и игр. Глубокое понимание методов getIntersections, intersect и работы с Curve обеспечивает точный контроль над геометрией и визуализацией.