Работаю с кодом, который отображает фигуру и позволяет с ней взаимодействовать. Мне нужно, чтобы ось вращения была прямой, под углом 45 градусов ко всем осям и проходила через начало координат
Код: "using System;
using System.Drawing;
using System.Windows.Forms;

namespace LABA003
{
    public partial class MainForm : Form
    {
        private const int GRAPH_SIZE = 400; // Размер области рисования
        private Point3D[] figureCoords; // Массив для хранения 3D координат фигуры
        private PointF[] projectedCoords; // Массив для хранения 2D проекций для отрисовки
        private Color cubeColor = Color.LightBlue; // Начальный цвет куба
        private float axisLineWidth = 1.0f; // Толщина линий для осей
        private float figureLineWidth = 1.0f; // Толщина линий для фигуры
        private int colorState = 0;
        private System.Windows.Forms.Timer rotationTimer; // Таймер для вращения
        private bool isRotating = false; // Флаг для отслеживания вращения
        private int speedLevel = 0; // Variable to keep track of speed levels


        public MainForm()
        {
            InitializeComponent(); // Инициализация компонентов формы
            this.DoubleBuffered = true; // Включение двойной буферизации для уменьшения мерцания
            figureCoords = null; // Устанавливаем фигуру в null при старте

            // Инициализация таймера
            rotationTimer = new System.Windows.Forms.Timer();
            rotationTimer.Interval = 100; // Интервал в миллисекундах
            rotationTimer.Tick += RotationTimer_Tick; // Подписываемся на событие срабатывания таймера
        }

        // Обработчик события рисования PictureBox
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics graph = e.Graphics; // Получение графического контекста
            DrawAxes(graph); // Рисуем оси на графике

            if (figureCoords != null) // Проверка на наличие фигуры
            {
                DrawFigure(graph); // Рисуем фигуру только если она инициализирована
            }
        }

        // Метод для очищения/сброса фигуры
        private void btnClear_Click(object sender, EventArgs e)
        {
            figureCoords = null; // Сбрасываем фигуру
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox для очистки
        }

        // Метод для инициализации гексаэдра (куба)
        private void InitializeFigure()
        {
            figureCoords = new Point3D[] // Устанавливаем координаты для куба
            {
                new Point3D(0, 50, 0), // 0
                new Point3D(50, 0, 50), // 1
                new Point3D(50, 0, -50), // 2
                new Point3D(-50, 0, -50), // 3
                new Point3D(-50, 0, 50), // 4
                new Point3D(0, -50, 0), // 5
               // new Point3D(50, -50, -50), // 6
               // new Point3D(-50, -50, -50) // 7
            };
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox после инициализации
        }

        // Обработчик нажатия кнопки для рисования фигуры
        private void btnDrawFigure_Click(object sender, EventArgs e)
        {
            InitializeFigure(); // Инициализируем фигуру при нажатии кнопки
        }

        // Метод для рисования осей X и Y в PictureBox
        private void DrawAxes(Graphics graph)
        {
            int width = pictureBox1.Width; // Получаем ширину PictureBox
            int height = pictureBox1.Height; // Получаем высоту PictureBox

            int centerX = width / 2; // Вычисляем координату центра по X
            int centerY = height / 2; // Вычисляем координату центра по Y

            // Рисуем вертикальную (ось Y) и горизонтальную (ось X) оси
            graph.DrawLine(new Pen(Color.Black, axisLineWidth), centerX, 0, centerX, height); // Ось Y
            graph.DrawLine(new Pen(Color.Black, axisLineWidth), 0, centerY, width, centerY); // Ось X
        }

        // Метод для рисования фигуры с использованием 2D проекций
        private void DrawFigure(Graphics graph)
        {
            projectedCoords = ProjectTo2D(figureCoords); // Проектируем 3D координаты в 2D

            if (projectedCoords != null) // Проверка успешности проекции
            {
                // Задание цвета для граней
               Brush faceBrush = new SolidBrush(cubeColor); // Цвет грани

                // Рисуем грани
                // Верхняя грань 1
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[0], projectedCoords[1], projectedCoords[2]
        });

                // Верхняя грань 2
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[0], projectedCoords[2], projectedCoords[3]
        });

                // Верхняя грань 3
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[0], projectedCoords[3], projectedCoords[4]
        });

                // Верхняя грань 4
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[0], projectedCoords[4], projectedCoords[1]
        });

                // Нижняя грань 1
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[5], projectedCoords[1], projectedCoords[2]
        });

                // Нижняя грань 2
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[5], projectedCoords[2], projectedCoords[3]
        });
                // Нижняя грань 3
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[5], projectedCoords[3], projectedCoords[4]
        });

                // Нижняя грань 4
                graph.FillPolygon(faceBrush, new PointF[] {
            projectedCoords[5], projectedCoords[4], projectedCoords[1]
        });


                // Соединяем грани по рёбрам
                Pen edgePen = new Pen(Color.Red, figureLineWidth);

                // Рёбра куба
                graph.DrawLine(edgePen, projectedCoords[0], projectedCoords[1]);
                graph.DrawLine(edgePen, projectedCoords[0], projectedCoords[2]);
                graph.DrawLine(edgePen, projectedCoords[0], projectedCoords[3]);
                graph.DrawLine(edgePen, projectedCoords[0], projectedCoords[4]);

                graph.DrawLine(edgePen, projectedCoords[1], projectedCoords[2]);
                graph.DrawLine(edgePen, projectedCoords[2], projectedCoords[3]);
                graph.DrawLine(edgePen, projectedCoords[3], projectedCoords[4]);
                graph.DrawLine(edgePen, projectedCoords[4], projectedCoords[1]);

                graph.DrawLine(edgePen, projectedCoords[5], projectedCoords[1]);
                graph.DrawLine(edgePen, projectedCoords[5], projectedCoords[2]);
                graph.DrawLine(edgePen, projectedCoords[5], projectedCoords[3]);
                graph.DrawLine(edgePen, projectedCoords[5], projectedCoords[4]);

                // Обводим для четкости
                graph.DrawPolygon(new Pen(Color.Red, figureLineWidth), projectedCoords); // Контур
            }
        }

        // Метод для проекции 3D точек в 2D для отрисовки
        private PointF[] ProjectTo2D(Point3D[] coords)
        {
            PointF[] points = new PointF[coords.Length]; // Создаем массив для 2D точек
            for (int i = 0; i < coords.Length; i++)
            {
                // Преобразуем 3D координаты в 2D с учетом GRAPH_SIZE
                points[i] = new PointF(GRAPH_SIZE / 2 + coords[i].X, GRAPH_SIZE / 2 - coords[i].Y);
            }
            return points; // Возвращаем массив проекционных точек
        }
        private void RotationTimer_Tick(object sender, EventArgs e)
        {
            if (figureCoords != null)
            {
                RotateY((float)(Math.PI / 180 * 5)); // Вращаем вокруг оси Y на 5 градусов
            }
        }

        private void btnToggleRotation_Click(object sender, EventArgs e)
        {
            // Cycle through the speed levels: 0 (normal), 1 (double speed), 2 (stop)
            speedLevel = (speedLevel + 1) % 3;

            switch (speedLevel)
            {
                case 0:
                    rotationTimer.Interval = 100; // Normal speed (current)
                    btnToggleRotation.Text = "Speed Up"; // Indicate next action
                    break;
                case 1:
                    rotationTimer.Interval = 50; // Double speed
                    btnToggleRotation.Text = "Speed Up Again"; // Indicate next action
                    break;
                case 2:
                    rotationTimer.Stop(); // Stop rotation
                    btnToggleRotation.Text = "Start"; // Change text for starting again
                    return; // Exit to prevent starting the timer
            }

            rotationTimer.Start(); // Start rotation with the updated speed
        }
        // Метод для изменения цвета куба
        private void btnChangeColor_Click(object sender, EventArgs e)
        {
            switch (colorState)
            {
                case 0:
                    cubeColor = Color.Purple; // Первый вызов - фиолетовый
                    break;
                case 1:
                    cubeColor = Color.Green; // Второй вызов - зеленый
                    break;
                case 2:
                    cubeColor = Color.DarkBlue; // Третий вызов - DarkBlue
                    break;
            }

            colorState = (colorState + 1) % 3; // Переход к следующему состоянию
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для увеличения толщины линий
        private void btnIncreaseLineWidth_Click(object sender, EventArgs e)
        {
            figureLineWidth += 1.0f; // Увеличиваем толщину линий фигуры на 1
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для трансляции фигуры в 3D пространстве
        private void Translate(Point3D translation)
        {
            for (int i = 0; i < figureCoords.Length; i++)
            {
                // Изменяем координаты каждой точки на вектор трансляции
                figureCoords[i].X += translation.X;
                figureCoords[i].Y += translation.Y;
                figureCoords[i].Z += translation.Z;
            }
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для масштабирования фигуры на заданный коэффициент
        private void Scale(float factor)
        {
            for (int i = 0; i < figureCoords.Length; i++)
            {
                // Масштабируем координаты
                figureCoords[i].X *= factor;
                figureCoords[i].Y *= factor;
                figureCoords[i].Z *= factor;
            }
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для вращения фигуры вокруг оси X
        private void RotateX(float angle)
        {
            float cosA = (float)Math.Cos(angle); // Вычисляем косинус угла
            float sinA = (float)Math.Sin(angle); // Вычисляем синус угла

            // Найдем центр фигуры
            Point3D center = CalculateCenter();

            for (int i = 0; i < figureCoords.Length; i++)
            {
                // Перемещаем точку к началу координат
                float y = figureCoords[i].Y - center.Y;
                float z = figureCoords[i].Z - center.Z;

                // Применяем преобразование вращения
                figureCoords[i].Y = center.Y + y * cosA - z * sinA;
                figureCoords[i].Z = center.Z + y * sinA + z * cosA;
            }
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для вращения фигуры вокруг оси Y
        private void RotateY(float angle)
        {
            float cosA = (float)Math.Cos(angle);
            float sinA = (float)Math.Sin(angle);

            // Найдем центр фигуры
            Point3D center = CalculateCenter();

            for (int i = 0; i < figureCoords.Length; i++)
            {
                // Перемещаем точку к началу координат
                float x = figureCoords[i].X - center.X;
                float z = figureCoords[i].Z - center.Z;

                // Применяем преобразование вращения
                figureCoords[i].X = center.X + x * cosA + z * sinA;
                figureCoords[i].Z = center.Z - x * sinA + z * cosA;
            }
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для вращения фигуры вокруг оси Z
        private void RotateZ(float angle)
        {
            float cosA = (float)Math.Cos(angle);
            float sinA = (float)Math.Sin(angle);

            // Найдем центр фигуры
            Point3D center = CalculateCenter();

            for (int i = 0; i < figureCoords.Length; i++)
            {
                // Перемещаем точку к началу координат
                float x = figureCoords[i].X - center.X;
                float y = figureCoords[i].Y - center.Y;

                // Применяем преобразование вращения
                figureCoords[i].X = center.X + x * cosA - y * sinA;
                figureCoords[i].Y = center.Y + x * sinA + y * cosA;
            }
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Метод для вычисления центра фигуры
        private Point3D CalculateCenter()
        {
            float sumX = 0, sumY = 0, sumZ = 0;

            for (int i = 0; i < figureCoords.Length; i++)
            {
                sumX += figureCoords[i].X;
                sumY += figureCoords[i].Y;
                sumZ += figureCoords[i].Z;
            }

            return new Point3D(sumX / figureCoords.Length, sumY / figureCoords.Length, sumZ / figureCoords.Length);
        }

        // Обработчик нажатия кнопки для перерисовки осей
        private void btnDrawAxes_Click(object sender, EventArgs e)
        {
            pictureBox1.Invalidate(); // Вызываем перерисовку PictureBox
        }

        // Обработчик нажатия кнопки для положительной трансляции по оси X
        private void btnTranslateXPositive_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                Translate(new Point3D(10, 0, 0)); // Перемещаем фигуру положительно по оси x
            }
        }

        // Обработчик нажатия кнопки для отрицательной трансляции по оси X
        private void btnTranslateXNegative_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                Translate(new Point3D(-10, 0, 0)); // Перемещаем фигуру отрицательно по оси x
            }
        }

        // Обработчик нажатия кнопки для положительной трансляции по оси Y
        private void btnTranslateYPositive_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                Translate(new Point3D(0, 10, 0)); // Перемещаем фигуру положительно по оси y
            }
        }

        // Обработчик нажатия кнопки для отрицательной трансляции по оси Y
        private void btnTranslateYNegative_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                Translate(new Point3D(0, -10, 0)); // Перемещаем фигуру отрицательно по оси y
            }
        }

        // Обработчик нажатия кнопки для увеличения масштабирования фигуры
        private void btnScaleUp_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                Scale(1.2f); // Увеличиваем размер фигуры на коэффициент 1.2
            }
        }

        // Обработчик нажатия кнопки для уменьшения масштабирования фигуры
        private void btnScaleDown_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                Scale(0.8f); // Уменьшаем размер фигуры на коэффициент 0.8
            }
        }

        // Обработчик нажатия кнопки для вращения фигуры вокруг оси X на 30 градусов
        private void btnRotateX_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                RotateX((float)(Math.PI / 180 * 5)); // Преобразуем градусы в радианы для вращения
            }
        }

        // Обработчик нажатия кнопки для вращения фигуры вокруг оси Y на 30 градусов
        private void btnRotateY_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                RotateY((float)(Math.PI / 180 * 5)); // Преобразуем градусы в радианы для вращения
            }
        }

        // Обработчик нажатия кнопки для вращения фигуры вокруг оси Z на 30 градусов
        private void btnRotateZ_Click(object sender, EventArgs e)
        {
            if (figureCoords != null) // Проверяем, есть ли фигура
            {
                RotateZ((float)(Math.PI / 180 * 5)); // Преобразуем градусы в радианы для вращения
            }
        }

        // Обработчик события загрузки формы
        private void MainForm_Load(object sender, EventArgs e)
        {
            this.Text = "3D Transformations"; // Set form title
            speedLevel = 0; // Reset speed level to normal speed at loading
        }
    }

    // Структура для определения точки в 3D пространстве
    public struct Point3D
    {
        public float X, Y, Z; // Координаты в 3D
        public Point3D(float x, float y, float z) // Конструктор для структуры
        {
            X = x; // Установка координаты X
            Y = y; // Установка координаты Y
            Z = z; // Установка координаты Z
        }
    }
}"