Матрицы в Two.Matrix

В Two.js объект Two.Matrix используется для представления и управления аффинными преобразованиями в двухмерном пространстве. Матрица хранит значения, которые позволяют выполнять смещение (translation), масштабирование (scaling), вращение (rotation) и наклон (shear) объектов.

С точки зрения структуры, матрица реализована как 3×3, но для удобства и оптимизации хранения используется только 6 элементов:

[a, b, c, d, e, f]

где преобразование точки (x, y) вычисляется по формулам:

x' = a * x + c * y + e
y' = b * x + d * y + f

Это стандартная форма аффинной матрицы в компьютерной графике.


Инициализация и свойства

Создание новой матрицы осуществляется через конструктор:

let matrix = new Two.Matrix(a, b, c, d, e, f);

Если параметры не заданы, по умолчанию создается единичная матрица:

[1, 0, 0, 1, 0, 0]

Каждое свойство имеет прямой доступ:

  • matrix.a и matrix.d – элементы, отвечающие за масштабирование по X и Y.
  • matrix.b и matrix.c – элементы, отвечающие за наклон по осям.
  • matrix.e и matrix.f – элементы смещения по X и Y.

Основные методы Two.Matrix

identity()

Сбрасывает матрицу к единичной:

matrix.identity();

Результат:

[1, 0, 0, 1, 0, 0]

Используется для очистки всех предыдущих преобразований.


set(a, b, c, d, e, f)

Позволяет напрямую установить значения матрицы:

matrix.set(1, 0, 0, 1, 100, 50);

Это равносильно смещению объекта на (100, 50) без изменения масштаба или наклона.


multiply(matrixB)

Выполняет умножение текущей матрицы на другую матрицу matrixB. Результатом является комбинированное преобразование:

matrix.multiply(matrixB);

Важно понимать, что порядок умножения имеет значение, так как матрицы некоммутативны:

matrix.multiply(B) ≠ B.multiply(matrix)

invert()

Создает обратную матрицу, которая отменяет текущее преобразование:

matrix.invert();

Используется для вычисления исходных координат объекта после нескольких последовательных преобразований.


translate(x, y)

Добавляет смещение:

matrix.translate(50, 30);

Эквивалентно добавлению (50, 30) к текущему положению объекта, сохраняя все существующие вращения и масштабы.


scale(sx, sy)

Масштабирование по осям X и Y. Если sy не указан, используется sx:

matrix.scale(2);      // увеличивает в 2 раза по обеим осям
matrix.scale(1, 3);   // X остается 1, Y увеличен в 3 раза

rotate(angle)

Вращение на заданный угол в радианах:

matrix.rotate(Math.PI / 4);

Матрица автоматически комбинирует вращение с текущими смещениями и масштабами.


skewX(angle) и skewY(angle)

Применяют наклон по осям X и Y:

matrix.skewX(Math.PI / 6);
matrix.skewY(Math.PI / 6);

Эти методы особенно полезны для создания перспективных или «искаженных» эффектов.


clone()

Возвращает копию текущей матрицы, чтобы избежать изменения исходной при дальнейших операциях:

let copy = matrix.clone();

Работа с точками

Методы матрицы позволяют преобразовывать координаты точек:

let point = { x: 10, y: 20 };
matrix.multiply(point);  // изменяет point.x и point.y согласно матрице

Также можно использовать apply() для вычисления нового объекта без изменения исходного:

let newPoint = matrix.apply({ x: 10, y: 20 });

Комбинирование преобразований

Применение нескольких методов к одной матрице последовательно создаёт сложные эффекты:

matrix.identity()
      .translate(100, 50)
      .rotate(Math.PI / 4)
      .scale(2)
      .skewX(Math.PI / 6);

Порядок операций критически важен:

  • Сначала translate() — смещаем объект
  • Затем rotate() — вращаем относительно новой позиции
  • Потом scale() — масштабируем
  • В конце skewX() — добавляем наклон

Изменение порядка приведёт к совершенно другому результату.


Практическое применение

  1. Анимации – матрицы позволяют плавно изменять позицию, угол и масштаб объекта в цикле анимации.
  2. Композиция объектов – при объединении нескольких объектов в группу, матрицы группируют все преобразования, сохраняя локальные координаты.
  3. Интерактивность – преобразование координат мыши в локальные координаты объекта через обратную матрицу.
  4. Экспорт и SVG – Two.js использует матрицы для точного преобразования объектов при экспорте в векторные форматы.

Оптимизация и рекомендации

  • Использовать clone() при комбинировании сложных матриц, чтобы избежать побочных эффектов.
  • Сохранять порядок операций: translate → rotate → scale → skew.
  • Избегать частых invert(), так как вычисление обратной матрицы требует дополнительных ресурсов.
  • Использовать identity() перед новой анимацией, чтобы сбросить старые преобразования.

Встроенные вспомогательные функции

Two.js предоставляет удобные утилиты для работы с матрицами:

  • Two.Matrix.prototype.toString() – выводит матрицу в читаемом виде:
console.log(matrix.toString());
// "Matrix[ a=1, b=0, c=0, d=1, e=50, f=30 ]"
  • Two.Matrix.prototype.equals(matrixB) – проверка равенства двух матриц:
if (matrix.equals(matrixB)) {
  console.log("Матрицы идентичны");
}

Эти методы упрощают отладку и управление трансформациями при сложной анимации.


Матрица в Two.js является центральным элементом системы координат и трансформаций, обеспечивая гибкость и точность в работе с графикой на Canvas и SVG.