Создание интерактивного гиперкуба: эксперименты с трёхмерной графикой и выход в четвёртое измерение
Каждый раз, когда я сталкиваюсь с чем-то новым в разработке графики, я задаюсь вопросом: «А можно ли сделать что-то круче?» Создавать трёхмерные сцены в браузере — задача увлекательная, но уже привычная. Мы привыкли работать с кубами, сферами и прочими объектами в 3D-пространстве. Но что, если выйти за его пределы? А что, если ввести в игру четвёртое измерение? Именно эта мысль и привела меня к созданию интерактивного гиперкуба с помощью Three.js.
Почему гиперкуб?
Возможно, вам знакома идея гиперкуба, или тессеракта — четырехмерного аналога обычного куба. В отличие от простого куба, тессеракт содержит в себе дополнительную «глубину» — измерение, которое сложно визуализировать в реальном мире, но с помощью математики и графики его можно показать в проекции на трёхмерное пространство. Казалось бы, задача понятна, но как же подступиться к ней? В этой статье я хочу рассказать, как сделать интерактивную визуализацию гиперкуба, который вращается, меняет цвет и даже подстраивается под действия пользователя.
Интрига: как мы вообще будем рисовать объект с четырьмя измерениями в трёхмерном пространстве? Ответ, как всегда, прост и сложен одновременно — проекции. Но обо всём по порядку.
Начало: куб как точка входа
Первое, с чего мы начнём — это создание простого куба. Если вы уже работали с Three.js, то для вас это не будет чем-то новым. Мы создадим сцену, камеру, настроим рендер и добавим куб, который будет динамично вращаться.
Вот код, который рисует стандартный куб:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Создание куба с рёбрами
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.LineBasicMaterial({ color: 0x00ff00 });
const edges = new THREE.EdgesGeometry(geometry);
const line = new THREE.LineSegments(edges, material);
scene.add(line);
camera.position.z = 5;
Здесь мы создали обычный трёхмерный куб с зелёными рёбрами и камерой, которая находится на небольшом удалении от объекта. Это базовый уровень, но уже интерактивный. Я добавил возможность изменять цвет куба с помощью цветового инпута:
Но как быть с четвёртым измерением?
Здесь начинается самое интересное. Как вообще можно отобразить объект в четырёхмерном пространстве на экране?
Теория в действии
Представьте, как вы проецируете трёхмерный куб на двумерную поверхность (например, лист бумаги). Мы видим его тени и проекции, и по этим двумерным проекциям можем восстановить трёхмерный объект. Так же и с тессерактом — мы можем показать его «тени», спроецировав его на трёхмерное пространство, доступное для нашего восприятия.
Для этого нужно воспользоваться проекцией 4D-координат на 3D, чтобы рёбра и вершины гиперкуба можно было отобразить. Сначала нам нужно описать вершины гиперкуба:
const vertices = [
new THREE.Vector4(-1, -1, -1, -1),
new THREE.Vector4(1, -1, -1, -1),
new THREE.Vector4(1, 1, -1, -1),
new THREE.Vector4(-1, 1, -1, -1),
new THREE.Vector4(-1, -1, 1, -1),
new THREE.Vector4(1, -1, 1, -1),
new THREE.Vector4(1, 1, 1, -1),
new THREE.Vector4(-1, 1, 1, -1),
new THREE.Vector4(-1, -1, -1, 1),
new THREE.Vector4(1, -1, -1, 1),
new THREE.Vector4(1, 1, -1, 1),
new THREE.Vector4(-1, 1, -1, 1),
new THREE.Vector4(-1, -1, 1, 1),
new THREE.Vector4(1, -1, 1, 1),
new THREE.Vector4(1, 1, 1, 1),
new THREE.Vector4(-1, 1, 1, 1)
];
Но для тессеракта недостаточно просто нарисовать эти вершины. Мы должны соединить их рёбрами:
const edges = [
[0, 1], [1, 2], [2, 3], [3, 0],
[4, 5], [5, 6], [6, 7], [7, 4],
[0, 4], [1, 5], [2, 6], [3, 7],
[8, 9], [9, 10], [10, 11], [11, 8],
[12, 13], [13, 14], [14, 15], [15, 12],
[8, 12], [9, 13], [10, 14], [11, 15],
[0, 8], [1, 9], [2, 10], [3, 11],
[4, 12], [5, 13], [6, 14], [7, 15]
];
Каждое ребро соединяет две вершины — это основа для построения каркаса тессеракта.
Проблема: рендеринг и восприятие
Одной из самых больших проблем при визуализации многомерных объектов является то, что наш мозг не способен «видеть» четвертое измерение. Но здесь на помощь приходят повороты и анимация. Мы можем показать гиперкуб в разных проекциях, вращая его по разным осям, что создаёт иллюзию дополнительного измерения.
Функция для создания рёбер гиперкуба с использованием BufferGeometry:
function createTesseractEdges() {
const edges = [];
for (const [start, end] of edgeIndices) {
edges.push(vertices[start], vertices[end]);
}
const geometry = new THREE.BufferGeometry().setFromPoints(edges);
return geometry;
}
Когда пользователь выбирает тессеракт вместо обычного куба, мы просто меняем геометрию объекта:
shapeSelector.addEventListener('change', (event) => {
currentShape = event.target.value;
if (currentShape === "cube") {
line.geometry = new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1));
} else if (currentShape === "tesseract") {
line.geometry = createTesseractEdges();
}
});
Управляем вращением и цветом
Куб или тессеракт вращаются автоматически, но мы также можем управлять скоростью вращения с помощью ползунка:
const rotationSpeedSlider = document.getElementById('rotationSpeed');
rotationSpeedSlider.addEventListener('input', (event) => {
rotationSpeed = parseFloat(event.target.value);
});
Это делает объект более интерактивным: пользователи могут как менять скорость вращения, так и останавливать объект кликом мыши.
Что дальше?
Поработав над тессерактом, я осознал, что границы, по сути, не существуют. Многомерные объекты могут быть визуализированы, если уметь их правильно «проецировать» на наши привычные три измерения. Следующим шагом станет визуализация пенторакта (пятимерного гиперкуба), а может, и объектов с ещё большими измерениями.
Если вы хотите повторить этот эксперимент или доработать его под свои нужды, код доступен на моём GitHub, и, конечно же, буду рад вашим вопросам и предложениям.
Итог
Этот небольшой проект — прекрасный пример того, как с помощью простых инструментов вроде Three.js можно визуализировать сложные математические объекты и создавать интерактивные приложения, которые выходят за рамки привычного 3D-пространства. Гиперкубы и многомерные фигуры перестают быть абстракцией и превращаются в наглядные и понятные структуры, которые можно изучать, вращать и настраивать. Это не только расширяет границы нашего воображения, но и открывает путь к более глубокому пониманию математических и физических концепций, которые раньше казались недосягаемыми.