Выражения. Метод cross(vec1, vec2) After Effects
В выражениях Adobe After Effects метод cross(vec1, vec2) используется в выражениях для работы с векторами в двумерном (2D) или трёхмерном (3D) пространстве. Результатом является вектор, перпендикулярный плоскости, образованной входными векторами, что полезно для различных задач в анимации и 3D-пространстве, например, для расчёта нормалей или ориентации объектов.
Список эффектов и не только After Effects
Выражения After Effects список
cross(vec1, vec2)
vec1 — первый вектор [x1, y1, z1] vec2 — второй вектор [x2, y2, z2]
Для двух 3D-векторов vec1 = [x1, y1, z1] и vec2 = [x2, y2, z2] векторное произведение вычисляется как
cross(vec1, vec2) = [
y1 * z2 — z1 * y2,
z1 * x2 — x1 * z2,
x1 * y2 — y1 * x2
]
В чисто 2D-пространстве (где у нас есть только X и Y) метод cross() в After Effects напрямую использовать нельзя — он требует 3D-векторов [x,y,z]. Но есть приём, как это обойти.
В 2D у нас точки [x, y]. Чтобы использовать cross(), мы можем рассматривать их как вектора в 3D, добавив координату z=0:
v1 = [x1, y1, 0];
v2 = [x2, y2, 0];
result = cross(v1, v2);
Если оба вектора лежат в плоскости XY (z=0), то их векторное произведение будет направлено вдоль оси Z.
v1 = [1, 0, 0];
v2 = [0, 1, 0];
cross(v1, v2); // [0, 0, 1]
Определить направление поворота (лево/право)
v1 = [100, 0, 0];
v2 = [0, 100, 0];
c = cross(v1, v2);
sign = c[2]; // если положительное → поворот «против часовой», если отрицательное → «по часовой»
В 2D-графике часто используют скалярное аналог векторного произведения для определения «направления вращения», но cross() работает по-настоящему в 3D.
Результат cross(v1, v2) может быть направлен либо «вверх» от плоскости, либо «вниз» — то есть есть два возможных нормальных вектора, противоположные друг другу.
Какой из них возвращает cross() — зависит от порядка векторов (v1 × v2 ≠ v2 × v1).
cross(v1, v2) возвращает новый вектор-результат.
У этого вектора есть только направление и длина, но нет «привязки к месту».
По умолчанию он всегда рассматривается как вектор из начала координат (0,0,0).
То есть:
Если v1 и v2 — это позиции слоёв (вектора от начала координат до их Anchor Point),
то результат cross(v1, v2) — это тоже вектор, который начинается в (0,0,0) и указывает в перпендикулярном направлении.
Результат cross() всегда считается вектором из начала координат (0,0,0).
Если нужно «переместить» его начало в другую точку, просто прибавь эту точку к вектору.
A = thisComp.layer(«Null 1»).toWorld([0,0,0]);
B = thisComp.layer(«Null 2»).toWorld([0,0,0]);
crossVec = cross(A, B); // вектор из (0,0,0)
result = A + normalize(crossVec) * 200;
// теперь вектор начинается в точке A и уходит в сторону нормали
—————
4
Выражение вычислит вектор, перпендикулярный позициям Пусто 1 и Пусто 2 в виде массива [x, y, z]
vec1 = thisComp.layer(«Пусто 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Пусто 2»).transform.position; // Вектор 2
cross(vec1, vec2); // Возвращает перпендикулярный вектор
——-
1
Выражение вычислит вектор, перпендикулярный позициям Text 1 и Text 2 в виде массива [x, y, z] Полученные числовые значения можно применить например к свойству Ориентация слоя Text 3
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
cross(vec1, vec2); // Возвращает перпендикулярный вектор
Выражение для слоя Text свойства Исходный текст, чтобы видеть числовые значения которые возвращает выражение
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
x = cross(vec1, vec2); // Возвращает перпендикулярный вектор[x[0].toFixed(0), x[1].toFixed(0), x[2].toFixed(0)];
transform.position + time * 100; //Выражение для анимации Положения по оси Х слоя Text 1
———
1
Выражение для свойства Поворот Х слоя Text 3
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
x = cross(vec1, vec2); // Возвращает перпендикулярный вектор
x[1].toFixed(0);
—————
2
Сделать так, чтобы 3D-слой всегда был перпендикулярен двум другим 3D-слоям. Можно применить к свойству Ориентация слоя Text 3
// Получаем позиции двух слоёв
var vec1 = thisComp.layer(«Text 1»).transform.position;
var vec2 = thisComp.layer(«Text 2»).transform.position;
// Вычисляем нормаль (перпендикулярный вектор)
var normal = cross(vec1, vec2);
// Преобразуем вектор в углы ориентации (в градусах)
lookAt([0, 0, 0], normal);
lookAt([0, 0, 0], normal) заставляет слой ориентироваться по нормали, вычисленной с помощью cross(). Слой Text 3 будет перпендикулярен плоскости, образованной позициями Text 1 и Text 2.
transform.position + time * 100; //Выражение для анимации Положения по оси Х слоя Text 1
transform.position[1] + time * 100; //Выражение для анимации Положения по оси Y слоя Text 2
———
3
Выражение для свойства Позиция слоя Text 3
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
normal = normalize(cross(vec1, vec2)); // Возвращает перпендикулярный вектор[normal[0] * (-1000), normal[1] * 1000, normal[2] * (-100)];
Выражение для слоя Text чтобы видеть числовые результаты вычисления
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
normal = normalize(cross(vec1, vec2)); // Возвращает перпендикулярный вектор[(normal[0] * (-1000)).toFixed(0), (normal[1] * 1000).toFixed(0), (normal[2] * (-100)).toFixed(0)];
transform.position + time * 100; //Выражение для анимации Положения по оси Х слоя Text 1
transform.position[1] + time * 100; //Выражение для анимации Положения по оси Y слоя Text 2
———
3
Выражение для свойства Положение слоя Text 3 Вариант 2
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
normal = normalize(cross(vec1, vec2)); // Возвращает перпендикулярный вектор[transform.position[0] + normal[0] * 200, transform.position[1] + normal[1] * 300, transform.position[2] + normal[2] * 200];
Выражение для слоя Text чтобы видеть числовые результаты вычисления
vec1 = thisComp.layer(«Text 1»).transform.position; // Вектор 1
vec2 = thisComp.layer(«Text 2»).transform.position; // Вектор 2
normal = normalize(cross(vec1, vec2)); // Возвращает перпендикулярный вектор[(transform.position[0] + normal[0] * 200).toFixed(0), (transform.position[1] + normal[1] * 300).toFixed(0), (transform.position[2] + normal[2] * 200).toFixed(0)];
transform.position + time * 100; //Выражение для анимации Положения по оси Х слоя Text 1
transform.position[1] + time * 100; //Выражение для анимации Положения по оси Y слоя Text 2