Выражения. Метод 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