Three.js предоставляет возможность создавать сложные траектории движения объектов в 3D-пространстве с помощью кривых. Наиболее часто используемые классы для этого — CatmullRomCurve3 и QuadraticBezierCurve3, позволяющие задавать плавные пути и реализовывать анимации с точным контролем положения объекта во времени.
CatmullRomCurve3 реализует кривую типа Catmull-Rom, проходящую через заданный набор точек. Ключевой особенностью является гладкое прохождение через все контрольные точки, без необходимости ручного вычисления углов наклона или касательных.
const points = [
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(10, 5, 0),
new THREE.Vector3(20, 0, 5),
new THREE.Vector3(30, 5, 0)
];
const curve = new THREE.CatmullRomCurve3(points);
true или false). При замкнутой кривой
последний сегмент соединяется с первым.Генерация точек для визуализации или анимации осуществляется с помощью метода getPoints() или getPoint(t):
const divisions = 50;
const curvePoints = curve.getPoints(divisions); // массив точек
const pointAtHalf = curve.getPoint(0.5); // точка на середине кривой
Для анимации объекта вдоль кривой используется метод
getPoint(t), где t изменяется от 0 до
1.
let t = 0;
function animate() {
requestAnimationFrame(animate);
t += 0.001;
if (t > 1) t = 0;
object.position.copy(curve.getPoint(t));
}
QuadraticBezierCurve3 позволяет строить кривую второго порядка через начальную точку, конечную точку и одну контрольную точку. Этот тип кривой полезен для анимации с плавными дуговыми движениями.
const start = new THREE.Vector3(0, 0, 0);
const control = new THREE.Vector3(10, 15, 5);
const end = new THREE.Vector3(20, 0, 0);
const curve = new THREE.QuadraticBezierCurve3(start, control, end);
Методы getPoint(t) и getPoints(divisions) работают аналогично CatmullRomCurve3:
const points = curve.getPoints(20);
const midPoint = curve.getPoint(0.5);
t = 0 соответствует началу кривой, t = 1 —
концу.requestAnimationFrame для создания анимаций.Анимация по кривой строится по принципу итеративного
изменения параметра t с последующим обновлением
позиции объекта:
let t = 0;
const speed = 0.002;
function animate() {
requestAnimationFrame(animate);
t += speed;
if (t > 1) t = 0;
object.position.copy(curve.getPoint(t));
renderer.render(scene, camera);
}
animate();
Для более реалистичного движения используется вычисление касательной к кривой, позволяющей ориентировать объект вдоль пути:
const tangent = curve.getTangent(t).normalize();
object.lookAt(object.position.clone().add(tangent));
Это особенно важно для камер, транспортных средств или объектов, имитирующих физическое движение по маршруту.
Для отладки и визуального контроля траектории удобно использовать THREE.Line:
const points = curve.getPoints(100);
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
const line = new THREE.Line(geometry, material);
scene.add(line);
100–200) делает
кривую более гладкой.Можно создавать сложные траектории, комбинируя несколько кривых с помощью THREE.CurvePath:
const path = new THREE.CurvePath();
path.add(curve1);
path.add(curve2);
const points = path.getPoints(200);
По умолчанию движение по кривой с равномерным шагом t
может выглядеть неровным, если сегменты кривой имеют
разную длину. Для решения используют getUtoTmapping(u),
который позволяет равномерно распределять движение по длине кривой:
const u = 0.5; // половина длины кривой
const t = curve.getUtoTmapping(u);
object.position.copy(curve.getPoint(t));
Это обеспечивает постоянную скорость движения независимо от кривизны траектории.
lookAt делает
движение более реалистичным и плавным.Эти инструменты позволяют создавать динамичные сцены с плавными и точными траекториями, что является ключевым аспектом интерактивной графики в Three.js.