LeCodesdocs

Vec2 и Vec3

Векторные типы SDK. Поля — обычные изменяемые числа (v.x = 3 работает), но каждый метод чистый: a.add(b) возвращает НОВЫЙ вектор и никогда не трогает a. Единственные мутаторы — set и copy. Оба типа делят один и тот же API; Vec3 добавляет операции только для 3D (векторное произведение как вектор, преобразования кватернионом и матрицей).

Везде, где принимается вектор, подойдёт и «сырой» кортеж (Vec2Like / Vec3Like): обёртка, кортеж [x, y] / [x, y, z], number[] или Float32Array. Векторы итерируемы — их можно разворачивать и деструктурировать как кортежи.

Обзор

TypeScript
const toTarget = new Vec3(target.position).sub(pos)
const dir = toTarget.normalize()                    // чисто — toTarget не меняется
pos = pos.add(dir.scale(speed * dt))                // переприсваиваем; add() возвращает новый вектор

node.position = [0, 1, 0]                           // сырые кортежи работают везде, где ждут Vec3
const [x, y, z] = node.position                     // векторы деструктурируются как кортежи
if (toTarget.lengthSq() < 4) attack()               // дешевле, чем length(), для проверки дистанции

Создание

TypeScript
new Vec2(x?, y?)                 // компоненты; по умолчанию (0, 0)
new Vec2([3, 4])                 // или копия любого Vec2Like
new Vec3(x?, y?, z?)             // по умолчанию (0, 0, 0)
Vec3.from(v: Vec3Like): Vec3

Vec2.zero / .one / .up / .down / .left / .right
Vec3.zero / .one / .up / .down / .left / .right / .forward / .back
Заметка

Статические константы — это геттеры: каждое обращение возвращает свежий экземпляр, поэтому менять его безопасно. Vec3.forward — это −Z (камеры смотрят вдоль −Z), Vec3.back — это +Z. Vec2.up — это +Y (2D-мир имеет ось Y вверх).

Мутация — только эти два метода меняют this

TypeScript
v.set(x, y): this                // Vec3: set(x, y, z)
v.copy(other: Vec2Like): this

Арифметика (чистая — каждый метод возвращает новый вектор)

TypeScript
a.add(b)   a.sub(b)   a.mul(b)   a.div(b)     // покомпонентно; b может быть кортежем
a.scale(s)                                     // умножить на скаляр
a.scaleAndAdd(b, s)                            // a + b·s за один вызов
a.negate()
a.withX(x)  a.withY(y)                         // копия с заменой одной компоненты (Vec3: withZ)

Произведения и меры

TypeScript
a.dot(b): number
a.length(): number          a.lengthSq(): number
a.distanceTo(b): number     a.distanceSqTo(b): number
a.angle(b): number          // угол между векторами, РАДИАНЫ (0, если один из них нулевой)
a.normalize(): Vec          // единичный вектор; нулевой вектор нормализуется в нулевой

Для сравнений предпочитайте варианты с Sq — они пропускают извлечение корня.

Интерполяция и зажатие

TypeScript
a.lerp(b, t)                 // покомпонентное смешивание, t обычно 0..1
a.clamp(min, max)            // покомпонентный зажим между двумя векторами
a.min(b)   a.max(b)          // покомпонентный минимум / максимум

Только Vec2

TypeScript
a.cross(b): number           // скалярная z-компонента 3D-векторного произведения — знаковая площадь
a.perp(): Vec2               // (-y, x): перпендикуляр, повёрнутый на 90° против часовой
a.rotate(rad, origin?)       // поворот против часовой на РАДИАНЫ вокруг origin (по умолчанию [0, 0])
a.heading(): number          // atan2(y, x) — угол вектора в РАДИАНАХ

Только Vec3

TypeScript
a.cross(b): Vec3
a.reflect(normal)            // отражение относительно ЕДИНИЧНОЙ нормали: v − 2(v·n)n
a.project(onto)              // проекция a на `onto` (нулевой `onto` → нулевой вектор)
a.rotateX(rad, origin?)      // поворот точки вокруг оси через origin, РАДИАНЫ
a.rotateY(rad, origin?)
a.rotateZ(rad, origin?)
a.rotate(q)                  // поворот кватернионом Quat или сырым [x, y, z, w]
a.transform(m)               // преобразование как ТОЧКИ матрицей Mat4 / сырым column-major массивом на 16
                             // — применяет перенос и перспективное деление

Для направления (без переноса) используйте Mat4.transformDirection, а не transform.

Совместимость

TypeScript
a.equals(b, eps? /* 1e-6 */): boolean   // сравнение с относительным эпсилон
a.clone(): Vec
a.toArray(): [number, number]           // Vec3: [number, number, number]
const [x, y] = a; [...a]                // итерируемый

Подводные камни

TypeScript
// ✗ ждать, что методы мутируют — они этого не делают
dir.normalize()                          // результат отброшен; dir не изменился
dir = dir.normalize()                    // ✓ переприсвоить

// ✗ менять копию трансформа узла — геттеры возвращают свежие значения
node.position.x = 3                      // тихий no-op (см. Соглашения)
node.x = 3                               // ✓

Смотрите также

  • Mathf — скалярные помощники (clamp, damp, smoothDamp для массивов).
  • Quat — повороты; Vec3.rotate(q) — это Quat.rotateVec3 с другой стороны.
  • Mat4 — полные преобразования; transformPoint / transformDirection.