Кривые: CatmullRomCurve3, CubicBezierCurve3

Three.js предоставляет мощные инструменты для работы с кривыми в трехмерном пространстве. Среди них особое место занимают CatmullRomCurve3 и CubicBezierCurve3, которые позволяют создавать гладкие линии и сложные траектории для анимации, моделирования и визуализации.


CatmullRomCurve3

CatmullRomCurve3 реализует интерполяцию кривой через заданные точки с помощью алгоритма Catmull–Rom. Кривая проходит через все контрольные точки, что делает её удобной для создания плавных траекторий движения объектов.

Создание кривой:

const points = [
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(10, 10, 0),
    new THREE.Vector3(20, 0, 0),
    new THREE.Vector3(30, 10, 0)
];

const curve = new THREE.CatmullRomCurve3(points, closed = false, 'centripetal');

Параметры конструктора:

  • points — массив объектов THREE.Vector3, через которые будет проходить кривая.
  • closed — булев тип, указывающий, замкнута ли кривая. Если true, первая и последняя точки соединяются.
  • curveType — тип интерполяции: 'centripetal', 'chordal' или 'catmullrom'. 'centripetal' часто используется для предотвращения самопересечений кривой.

Методы:

  • getPoint(t) — возвращает точку на кривой для параметра t от 0 до 1.
  • getPoints(divisions) — возвращает массив точек, равномерно распределенных по кривой. Полезно для создания геометрии или визуализации линий.

Пример визуализации кривой:

const geometry = new THREE.BufferGeometry().setFromPoints(curve.getPoints(50));
const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
const curveObject = new THREE.Line(geometry, material);
scene.add(curveObject);

CubicBezierCurve3

CubicBezierCurve3 используется для создания кубических кривых Безье в трехмерном пространстве. Кривая определяется четырьмя контрольными точками: начальной, конечной и двумя управляющими.

Создание кривой:

const curve = new THREE.CubicBezierCurve3(
    new THREE.Vector3(-10, 0, 0),   // start point
    new THREE.Vector3(-5, 15, 0),   // control point 1
    new THREE.Vector3(20, 15, 0),   // control point 2
    new THREE.Vector3(10, 0, 0)     // end point
);

Методы:

  • getPoint(t) — возвращает точку на кривой для значения t от 0 до 1.
  • getPoints(divisions) — генерирует массив точек для построения линии или геометрии.
  • getTangent(t) — вычисляет вектор касательной в точке на кривой, что удобно для анимации объектов вдоль кривой.

Пример визуализации кривой:

const geometry = new THREE.BufferGeometry().setFromPoints(curve.getPoints(50));
const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
const curveObject = new THREE.Line(geometry, material);
scene.add(curveObject);

Сравнение CatmullRomCurve3 и CubicBezierCurve3

Характеристика CatmullRomCurve3 CubicBezierCurve3
Проходит через контрольные точки Да Нет, только начальная и конечная точки
Управление формой кривой Через выбор типа интерполяции Через два управляющих вектора
Использование Плавные траектории, анимация движения Точные кривые Безье для моделирования и анимации
Замыкание Поддерживается через параметр closed Замыкание реализуется вручную через соединение кривых

Работа с кривой для анимации объектов

Кривые в Three.js часто применяются для перемещения объектов вдоль траектории:

const sphere = new THREE.Mesh(
    new THREE.SphereGeometry(1, 16, 16),
    new THREE.MeshStandardMaterial({ color: 0x0000ff })
);
scene.add(sphere);

let t = 0;
function animate() {
    requestAnimationFrame(animate);
    t += 0.001;
    if(t > 1) t = 0;
    const point = curve.getPoint(t);
    sphere.position.set(point.x, point.y, point.z);
    renderer.render(scene, camera);
}
animate();

Использование метода getTangent(t) позволяет задавать ориентацию объекта вдоль кривой, что особенно важно для анимации транспортных средств или камер.


Преобразование кривой в геометрию

Three.js позволяет строить объемные объекты вдоль кривой, используя TubeGeometry:

const tubeGeometry = new THREE.TubeGeometry(curve, 100, 2, 8, false);
const tubeMaterial = new THREE.MeshStandardMaterial({ color: 0xffff00 });
const tubeMesh = new THREE.Mesh(tubeGeometry, tubeMaterial);
scene.add(tubeMesh);

Параметры TubeGeometry:

  • curve — объект кривой (CatmullRomCurve3 или CubicBezierCurve3).
  • tubularSegments — количество сегментов вдоль кривой.
  • radius — радиус трубы.
  • radialSegments — количество сегментов по окружности.
  • closed — замкнута ли труба.

Это позволяет создавать сложные 3D-трубопроводы, каналы, треки и любые другие объекты вдоль произвольной траектории.


Настройка скорости движения вдоль кривой

CatmullRomCurve3 поддерживает методы для равномерного распределения движения:

curve.getPointAt(u); // u - равномерный параметр от 0 до 1

getPointAt учитывает кривизну, что позволяет объекту двигаться с постоянной скоростью, в отличие от getPoint, где скорость может меняться из-за неравномерного распределения точек.


Советы по использованию кривых

  • Для гладких траекторий лучше использовать CatmullRomCurve3 с 'centripetal' интерполяцией.
  • Для точного контроля формы кривой — CubicBezierCurve3.
  • Для сложных траекторий можно комбинировать несколько кривых и использовать CurvePath.
  • Визуализация кривой с помощью Line или TubeGeometry помогает оценить форму и плотность сегментов.
  • Для анимации объектов вдоль кривой важно учитывать касательные для корректной ориентации.

Хотите, могу создать подробную схему, показывающую разницу между CatmullRomCurve3 и CubicBezierCurve3 с визуализацией кривых и касательных. Это сильно упрощает понимание их работы.