CurvePath и TubeGeometry на основе кривой

В Three.js работа с кривыми и путями позволяет создавать сложные формы и анимации объектов в 3D-пространстве. Основой для построения таких объектов служат классы Curve, CurvePath и геометрия TubeGeometry, которая строится вдоль кривой.


Класс CurvePath

CurvePath — это контейнер для кривых, который позволяет объединять несколько сегментов в единую траекторию. Он наследуется от Curve, что позволяет использовать его в местах, где требуется объект кривой.

Основные методы CurvePath
  • add(curve) — добавляет сегмент кривой в путь. Сегменты могут быть любого типа: LineCurve, QuadraticBezierCurve, CubicBezierCurve и др.
  • getPoint(t) — возвращает точку на пути, где t лежит в диапазоне [0, 1]. Метод автоматически учитывает все сегменты кривой.
  • getPoints(divisions) — возвращает массив точек на пути с равномерным делением по t.
  • createPointsGeometry(divisions) — создает объект BufferGeometry, содержащий вершины вдоль пути. Полезно для визуализации траектории.
  • closePath() — замыкает путь, соединяя последний сегмент с первым.
Пример объединения кривых
const path = new THREE.CurvePath();

const curve1 = new THREE.LineCurve3(
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(5, 5, 0)
);

const curve2 = new THREE.QuadraticBezierCurve3(
    new THREE.Vector3(5, 5, 0),
    new THREE.Vector3(7, 10, 0),
    new THREE.Vector3(10, 5, 0)
);

path.add(curve1);
path.add(curve2);

const points = path.getPoints(50);

В этом примере создается путь из двух сегментов: линейного и квадратичной кривой Безье. Метод getPoints возвращает массив из 51 точки для визуализации или дальнейшей генерации геометрии.


TubeGeometry: создание объёмной формы по кривой

TubeGeometry позволяет строить трёхмерный объект, «обволакивающий» кривую, создавая трубку с заданным радиусом. Основные параметры конструктора:

THREE.TubeGeometry(path, tubularSegments, radius, radialSegments, closed)
  • path — объект кривой (Curve или CurvePath), вдоль которой строится труба.
  • tubularSegments — количество сегментов вдоль кривой (чем больше, тем плавнее).
  • radius — радиус трубы.
  • radialSegments — количество сегментов по окружности трубы (толщина сетки).
  • closed — булевое значение, указывающее, замкнут путь или нет.
Пример создания трубы вдоль кривой
const curve = new THREE.CatmullRomCurve3([
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(5, 5, 0),
    new THREE.Vector3(10, 0, 0),
    new THREE.Vector3(15, 5, 0)
]);

const tubeGeometry = new THREE.TubeGeometry(curve, 64, 1, 16, false);
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const tubeMesh = new THREE.Mesh(tubeGeometry, material);

scene.add(tubeMesh);

В этом примере используется кривая CatmullRomCurve3, которая проходит через заданные точки, и создается красная труба с плавной формой.


Тонкости работы с TubeGeometry

  1. Выравнивание вдоль кривой Геометрия трубы ориентируется вдоль касательных к кривой. Three.js автоматически строит ортонормальный фрейм (Frenet frame), который предотвращает скручивание и деформацию при сложных изгибах.

  2. Замкнутые и разомкнутые пути Если closed = true, TubeGeometry соединяет начало и конец кривой, создавая замкнутый тороидальный объект. Для этого путь должен быть плавно замкнут.

  3. Количество сегментов

    • tubularSegments влияет на гладкость вдоль кривой.
    • radialSegments определяет качество окружности трубы: слишком мало — полигоны заметны, слишком много — повышенная нагрузка на рендеринг.
  4. Материалы и текстурирование TubeGeometry поддерживает любые материалы Three.js. Для текстурирования можно использовать координаты UV, которые автоматически создаются вдоль длины и окружности трубы.


Взаимодействие CurvePath и TubeGeometry

Использование CurvePath с TubeGeometry позволяет строить сложные трубоподобные объекты из нескольких кривых, объединённых в один путь. Основные шаги:

  1. Создать CurvePath и добавить сегменты кривой.
  2. При необходимости замкнуть путь с помощью closePath().
  3. Передать объект пути в TubeGeometry.
  4. Настроить сегментацию и радиус трубы.
  5. Добавить полученный меш в сцену.
Пример сложного пути с несколькими сегментами
const path = new THREE.CurvePath();

path.add(new THREE.LineCurve3(
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(5, 0, 0)
));

path.add(new THREE.QuadraticBezierCurve3(
    new THREE.Vector3(5, 0, 0),
    new THREE.Vector3(7, 5, 0),
    new THREE.Vector3(10, 0, 0)
));

const tubeGeometry = new THREE.TubeGeometry(path, 100, 0.5, 12, false);
const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
const mesh = new THREE.Mesh(tubeGeometry, material);

scene.add(mesh);

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


Применение и оптимизация

  • Анимации по кривой: точки, полученные методом getPoints или getPoint, используются для перемещения объектов вдоль пути.
  • Сложные органические формы: трубы с кривыми создают линии для вен, рельефов, трассировки проводов и декоративных элементов.
  • Оптимизация сегментов: для производительности важно подобрать минимальное количество tubularSegments и radialSegments, обеспечивающее визуальную гладкость без лишней нагрузки на GPU.

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