javascript

Создание гиперкуба с помощью Three.js: как увидеть четвертое измерение?

  • понедельник, 30 сентября 2024 г. в 00:00:05
https://habr.com/ru/articles/846772/

Задавались ли вы когда-нибудь вопросом, можно ли выйти за рамки привычных трёх измерений? Мы привыкли видеть мир в 3D: кубы, сферы, пирамиды — все эти объекты легко вообразить и визуализировать. Но что, если мы попробуем заглянуть в четвёртое измерение? Это звучит как научная фантастика, но в мире математики и компьютерной графики всё возможно.

Сегодня я расскажу вам, как создать интерактивный гиперкуб, или тессеракт — четырехмерный аналог обычного куба. Мы будем использовать Three.js, популярную библиотеку для работы с 3D-графикой в браузере.

Почему гиперкуб?

Для начала, что же такое гиперкуб? В трёхмерном мире куб состоит из восьми вершин и шести граней. Гиперкуб, в свою очередь, — это четырёхмерный объект, который сложно представить в голове, но можно показать с помощью проекции на трёхмерное пространство. Это как если бы вы посмотрели на тень обычного куба на плоскости. Мы будем показывать не сам гиперкуб, а его "тень" в трёхмерном мире.

Зачем это нужно? Ну, если вы любите решать необычные задачи, вам просто интересно заглянуть в мир многомерных объектов, или вы увлечены математикой, эта тема точно для вас. А если вы разработчик, то этот проект станет отличным вызовом вашим навыкам работы с 3D-графикой.

Первый шаг: куб как отправная точка

Прежде чем взяться за гиперкуб, давайте создадим обычный куб в 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;

function animate() {
    requestAnimationFrame(animate);
    line.rotation.x += 0.01;
    line.rotation.y += 0.01;
    renderer.render(scene, camera);
}
animate();

Это базовый код, который создаёт вращающийся куб с зелёными рёбрами.

Но зачем останавливаться на трёх измерениях? Давайте погрузимся в мир четвёртого измерения и создадим тессеракт!

Четвертое измерение: гиперкуб в действии

Итак, как мы можем нарисовать объект с четырьмя измерениями в привычном трёхмерном пространстве? Ответ прост — с помощью проекций. Представьте, как мы проецируем тень трёхмерного объекта на двумерную плоскость. По сути, мы делаем то же самое, только теперь проецируем четырехмерный объект на трёхмерное пространство.

Вершины гиперкуба

Гиперкуб имеет 16 вершин (в отличие от 8 у обычного куба). Мы можем задать их как 4D координаты (x, y, z, w), где w — это дополнительная координата, представляющая четвёртое измерение:

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]
];

Как это работает?

Мы визуализируем гиперкуб, показывая его "тень" в 3D. Эту "тень" можно вращать по различным осям, создавая иллюзию четвёртого измерения. Рендерить гиперкуб можно через вращение по осям, добавив дополнительную математику для поворота в четвёртом измерении.

Интерактивность

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

<input type="color" id="colorPicker" value="#00ff00" />

Или дайте пользователю выбрать между обычным кубом и гиперкубом:

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();
    }
});

Итог

Гиперкуб — это не просто математическая абстракция. С помощью Three.js его можно визуализировать, вращать, менять его цвет и даже управлять скоростью вращения. Это помогает нам лучше понять многомерные объекты и выходит за рамки привычной 3D-графики.

P.S. Этот проект продолжает развиваться, и я планирую добавить новые возможности и улучшения, включая визуализацию многомерных объектов и новые функции взаимодействия. Если вам интересна тема многомерных пространств и их визуализация или у вас есть идеи по улучшению проекта — буду рад вашим предложениям и вкладу!

Вы можете присоединиться к разработке на GitHub или связаться со мной напрямую. Вместе мы сможем сделать этот проект ещё круче!

📂 GitHub: https://github.com/Laremin/HyperCube-Dream