Иииии мы тоже закончили с проектом! Он отнял у нас какое-то неадекватное количество времени... Тем не менее! То, что мы начинали как простой скринсейвер, по итогу разрослось до почти полноценного 3D-движка!
При запуске приложения вы можете видеть название текущей просматриаемой фигуры и собственно саму фигуру. Управление в сцене: 1. Стрелочки влево-вправо: движение камеры по оси Y; 2. Стрелочки вверх-вниз: zoom in/out (движение камеры по X); 3. PgUp/PgDown: движение камеры по оси Z; 4. Цифры: переключение фигур. Доступные фигуры: 0. Треугольная призма (показывается при запуске); 1. Куб; 2. Прямоугольник; 3. Икосаэдр (buggy); 4. Пирамида (also buggy);
Как это дело работает?
Вся математика держится на классах Fraction (обыкновенные дроби) и PointVector3D (набор координат в пространстве). В свою очередь с помощью PV3D реализован класс отрезка Segment, из которых состоят фигуры Shape (Array of Segment, в сущности).
Когда создаётся сцена с фигурой в ней, для каждого отрезка в фигуре проводится луч, соединяющий камеру и его концы. Затем вычисляются координаты точек пересечения этих лучей с плоскостью экрана.
Затем координаты точек в пространстве раскладываются по базису сторон экрана, приводятся в рамки уже физического экрана платформы Hack, после чего используется Screen.drawLine(), чтобы нарисовать на экране проекцию отрезка. Так рисуются все отрезки фигуры и получается так называемый Wireframe Viewport, или же изображение фигуры без граней, только с рёбрами.
Самое интересное находится в классах
Fraction, где реализована логика дробей (и тысяча и одна фича, созданные в попытках обойти переполнение жалкого 16-тибитного инта XD ),
PointVector3D, где описана математика векторов,
и Scene, где описан сам процесс рендера.
Код этих классов (особенно, само собой, Scene) местами плохо читаем из-за большого количества манипуляций над временными переменными и диспозами, но это сделано во избежание ошибок переполнения стека.
Бойко Владимир, Федоров Иван, Хрусталев Дмитрий
Stay sharp and math!