getLocationAt и позиция на кривые

В Paper.js кривые, линии и пути представлены объектами Path, которые могут состоять из сегментов (Segment) и кривых Безье. Для точной работы с положением на кривой используется метод getLocationAt(offset), позволяющий получить информацию о точке на пути на заданном расстоянии от начала.


Основы работы с getLocationAt

Метод вызывается у объекта Path и принимает один параметр:

var location = path.getLocationAt(offset);
  • offset — расстояние в пунктах (points) от начала пути.

  • Возвращаемое значение — объект типа CurveLocation, содержащий:

    • point — координаты точки на пути (Point).
    • curve — кривую Безье, к которой относится точка (Curve).
    • parameter — параметр кривой t в диапазоне [0,1].
    • segment — сегмент, ближайший к точке.
    • index — индекс кривой в пути.

Если offset выходит за пределы длины пути, возвращается null.

Пример использования:

var path = new Path();
path.add(new Point(50, 50));
path.add(new Point(150, 150));
path.add(new Point(250, 50));

var location = path.getLocationAt(100);
console.log(location.point); // Point на 100 единицах от начала
console.log(location.parameter); // t-параметр на соответствующей кривой

Связь с длиной пути

Метод getLocationAt тесно связан с path.length, который возвращает общую длину пути. Это позволяет:

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

Пример анимации точки вдоль пути:

var circle = new Path.Circle({
    center: [0, 0],
    radius: 5,
    fillColor: 'red'
});

var offset = 0;

function onFrame(event) {
    offset += 2;
    if (offset > path.length) offset = 0;
    var location = path.getLocationAt(offset);
    circle.position = location.point;
}

Здесь circle будет двигаться вдоль кривой, обновляя координаты в каждой кадре.


Параметр parameter и работа с кривыми

Каждая кривая Безье в Paper.js имеет параметр t в диапазоне [0,1], который указывает относительное положение точки на кривой. Связка getLocationAt(offset) и parameter позволяет:

  • Точно вычислять точку на кривой.
  • Делать интерполяцию между контрольными точками.
  • Определять направление касательной к кривой.
var curve = location.curve;
var t = location.parameter;
var tangent = curve.getTangentAt(t);
var normal = tangent.rotate(90); // перпендикуляр к кривой

Использование касательной и нормали открывает возможности для создания эффектов движения, выравнивания объектов по кривой и генерации сложных форм вдоль пути.


Получение сегмента и ближайшей кривой

getLocationAt возвращает объект CurveLocation, который содержит:

  • curve — кривая Безье, на которой находится точка.
  • segment — ближайший сегмент (начало или конец кривой).
  • index — индекс кривой в списке всех кривых пути.

Это важно при необходимости модифицировать сам путь:

var location = path.getLocationAt(120);
location.curve.setHandles(location.curve.segment1.point, location.curve.segment2.point.add([10, 0]));

Так можно динамически изменять кривую, не пересоздавая весь путь.


Обработка крайних случаев

  • Если путь пустой (path.segments.length === 0) или offset < 0 — возвращается null.
  • Если offset > path.length — также возвращается null.
  • Для замкнутого пути (path.closed = true) можно использовать offset % path.length, чтобы продолжать движение по кругу.

Практические применения

  1. Анимация объектов по кривой С помощью getLocationAt можно равномерно перемещать объекты вдоль пути, без привязки к количеству сегментов.

  2. Создание узоров и орнаментов На основе нормали и касательной можно расставлять объекты с нужным углом поворота вдоль кривой.

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

  4. Визуализация прогресса вдоль кривой Например, индикатор заполнения, где длина пути соответствует проценту выполнения.


Оптимизация и советы

  • Частое использование getLocationAt на длинных сложных путях может быть вычислительно затратным. Для анимации рекомендуется кэшировать длину пути и промежуточные точки.
  • Для кривых с большим количеством сегментов можно использовать getLocationAt(offset, true), где второй аргумент позволяет ускорить поиск с приближением по сегментам.
  • Всегда проверять, что возвращаемое значение не null перед использованием свойства point или curve.

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