Это часть курса Линейная алгебра с JavaScript.

Недавно я закончил рассказ о линейных преобразованиях с помощью JavaScript, двумерные примеры, отрисованные на сетке SVG (рассмотренные в этой части), работали хорошо, но чего-то не хватало - примеров в трехмерном пространстве… Репозиторий GitHub можно найти там и зафиксировать с состоянием этой истории там.

Цель

В этой части мы хотим создать компонент, который будет визуализировать линейное преобразование объекта в трехмерном пространстве. Конечный результат этой части вы можете увидеть ниже, также вы можете поиграть с ним здесь.

Компонент

Первая библиотека, которая приходит на ум, когда мы думаем о создании 3D в браузере, - это three.js. Итак, давайте установим его, а также библиотеку, чтобы пользователь мог перемещать камеру.

npm install --save three three-orbitcontrols

Мы создаем компонент, который получит матрицу в свойствах от родительского компонента и будет отображать анимированное преобразование куба. Вы можете увидеть структуру компонента ниже. Мы оборачиваем наш компонент функциями из styled-components и react-sizeme, чтобы иметь доступ к теме с цветами и определять, когда размер компонента изменился.

В конструкторе мы инициализируем состояние, которое содержит размер представления, чтобы мы могли сравнить его с новым в методе componentWillReceiveProps. Поскольку нам потребуется доступ к фактическому элементу DOM для внедрения ThreeJS renderer, мы используем ref в метод рендеринга.

В componentDidMount мы инициализируем все необходимое для анимации преобразования куба. Сначала мы создаем сцену и размещаем камеру. Затем мы создаем средство визуализации, устанавливаем цвет и размер и добавляем его к компоненту View.

Затем мы создаем объекты, которые будут визуализироваться - оси, куб и ребра куба. Поскольку мы будем изменять матрицу самостоятельно, мы устанавливаем для свойства matrixAutoUpdate куба и ребер значение false. Когда мы закончили создание объектов, мы добавляем их в сцену. Чтобы позволить пользователю перемещать камеру с помощью мыши, мы используем OrbitControls.

Затем мы конвертируем матрицы из нашей библиотеки в матрицы ThreeJS и получаем функции, которые будут возвращать цвет и матрицу преобразования в зависимости от времени. В componentWillUnmount мы отменяем кадр анимации и удаляем средство визуализации из DOM.

Без функции анимировать ничего не будет отображаться. Сначала мы обновляем матрицу преобразования как куба, так и его ребер, а также обновляем цвет куба. Затем мы все рендерим и запрашиваем кадр анимации.

В componentWillReceiveProps мы получаем текущий размер компонента, и если он отличается от предыдущего, мы обновляем состояние, изменяем размер средства визуализации и аспект камеры.

Анимации

Чтобы анимировать изменение цвета и преобразование, нам нужно написать функции, которые будут возвращать функции анимации. Прежде чем мы их рассмотрим, давайте рассмотрим некоторые преобразователи - функции из StackOverflow, которые преобразуют RGB в шестнадцатеричный и обратно, и функции, которые преобразуют матрицу из нашей библиотеки в ThreeJS и обратно.

Цвет

Во-первых, нам нужно рассчитать расстояния между каждой частью цветов (красный, зеленый, синий). Функция, которая вернет новый цвет, устанавливает отметку времени при первом вызове. Затем, зная расстояние между парой цветов и время, затраченное на первый вызов, вычисляется новый цвет RGB.

Линейное преобразование

Чтобы анимировать линейное преобразование, мы проделываем те же шаги. Мы находим разницу между матрицами и в функции анимации обновляем каждый компонент в зависимости от времени с первого вызова.

Достигните нового уровня сфокусированности и продуктивности с Increaser.org.