Главная Новости

Создание объемных фигур и демонстрация вращения


Опубликовано: 01.09.2018

видео Создание объемных фигур и демонстрация вращения

Терморезак

Среда программирования: 

В данной программе будет реализовано создание пирамиды с переливающимися гранями, куба с разноцветными гранями, их одновременное разобщенное вращение с помощью различных методов технологии OpenGL для языка С# - SharpGL - в проекте Windows Forms.



Работа с OpenGL в WPF почти ничем не отличается, поэтому смело можно использовать описанный в данном уроке материал. О том, как подключить SharpGL в WPF проекте или проекте Windows Forms, читайте тут http://grafika.me/lessons .

Из новых методов стоит отметить gl.Flush(); . Этот метод контролирует правильное обновление изображений.


Построение 3d-модели в AutoCAD

1. Создадим пирамиду

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


SketchUp: Сечение

Так как в предыдущем уроке уже было реализовано что-то подобное, сразу зададим вращение нашему объекту. Создадим переменную - значение угла поворота, и будем менять ее на каждой итерации отрисовки. Сам поворот реализуется методом gl.Rotate(angle, X.Xf, Y.Yf, Z.Zf); , где (X.Xf, Y.Yf, Z.Zf) - координаты вектора на оси, вокруг которой будет осуществляться вращение. Для начала просто посмотрим на пирамиду сбоку, для этого просто повращаем фигуру вокруг ее оси Y.

using System ; using System.Collections.Generic ; using System.ComponentModel ; using System.Data ; using System.Drawing ; using System.Linq ; using System.Text ; using System.Threading.Tasks ; using System.Windows.Forms ; using SharpGL ; namespace SharpGL { public partial class Form1 : Form { public Form1 ( ) { InitializeComponent ( ) ; } float rtri = 0 ; private void openGLControl1_OpenGLDraw ( object sender, RenderEventArgs args ) { // Создаем экземпляр OpenGL gl = this . openGLControl1 . OpenGL ; // Очистка экрана и буфера глубин gl . Clear ( OpenGL . GL_COLOR_BUFFER_BIT | OpenGL . GL_DEPTH_BUFFER_BIT ) ; // Пирамида ///////////////////////////// // Сбрасываем модельно-видовую матрицу gl . LoadIdentity ( ) ; // Сдвигаем перо влево от центра и вглубь экрана gl . Translate ( 0. 0f, 0 .0f, - 5. 0f ) ; // Вращаем пирамиду вокруг ее оси Y gl . Rotate ( rtri, 0 .0f, 1 .0f, 0 .0f ) ; // Рисуем треугольники - грани пирамиды gl . Begin ( OpenGL . GL_TRIANGLES ) ; // Front gl . Color ( 1. 0f, 0 .0f, 0 .0f ) ; gl . Vertex ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Color ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, 1 .0f ) ; gl . Color ( 0. 0f, 0 .0f, 1 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, 1 .0f ) ; // Right gl . Color ( 1. 0f, 0 .0f, 0 .0f ) ; gl . Vertex ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Color ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, - 1. 0f ) ; gl . Color ( 0. 0f, 0 .0f, 1 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, 1 .0f ) ; // Back gl . Color ( 1. 0f, 0 .0f, 0 .0f ) ; gl . Vertex ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Color ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, - 1. 0f ) ; gl . Color ( 0. 0f, 0 .0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, - 1. 0f ) ; // Left gl . Color ( 1. 0f, 0 .0f, 0 .0f ) ; gl . Vertex ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Color ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, 1 .0f ) ; gl . Color ( 0. 0f, 0 .0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, - 1. 0f ) ; gl . End ( ) ; // Контроль полной отрисовки следующего изображения gl . Flush ( ) ; // Меняем угол поворота rtri -= 3 .0f ; } } }

Вот что получим на выходе:

Изменим на gl.Rotate(rtri, 0.0f, 0.0f, 1.0f); , т.е. покрутим вокруг оси Z. Естественно, получим просто треугольник, который вращается вокруг своей вершины, в действительности - это вершина пирамиды, не принадлежащая основанию.

Самое интересное - вращение вокруг оси X. Увидим, что дна у пирамиды нет, т.к. оно и не было изначально отрисовано. Тем не менее, грани внутри пирамиды также переливаются.

2. Вращение куба.

Отрисуем грани с помощью метода gl.Begin(OpenGL.GL_QUADS); , зададим вращение вокруг оси (1.0, 1.0, 1.0).

using System ; using System.Collections.Generic ; using System.ComponentModel ; using System.Data ; using System.Drawing ; using System.Linq ; using System.Text ; using System.Threading.Tasks ; using System.Windows.Forms ; using SharpGL ; namespace SharpGL { public partial class Form1 : Form { public Form1 ( ) { InitializeComponent ( ) ; } float rquad = 0 ; private void openGLControl1_OpenGLDraw ( object sender, RenderEventArgs args ) { // Создаем экземпляр OpenGL gl = this . openGLControl1 . OpenGL ; // Очистка экрана и буфера глубин gl . Clear ( OpenGL . GL_COLOR_BUFFER_BIT | OpenGL . GL_DEPTH_BUFFER_BIT ) ; // Куб /////////////////////////////// // Сбрасываем модельно-видовую матрицу gl . LoadIdentity ( ) ; // Сдвигаем перо вправо от центра и вглубь экрана, но уже дальше gl . Translate ( 0. 0f, 0 .0f, - 10 .0f ) ; // Вращаем куб вокруг его диагонали gl . Rotate ( rquad, 1 .0f, 1 .0f, 1 .0f ) ; // Рисуем квадраты - грани куба gl . Begin ( OpenGL . GL_QUADS ) ; // Top gl . Color ( 0. 0f, 1 .0f, 0 .0f ) ; gl . Vertex ( 1. 0f, 1 .0f, - 1. 0f ) ; gl . Vertex ( - 1. 0f, 1 .0f, - 1. 0f ) ; gl . Vertex ( - 1. 0f, 1 .0f, 1 .0f ) ; gl . Vertex ( 1. 0f, 1 .0f, 1 .0f ) ; // Bottom gl . Color ( 1. 0f, 0 .5f, 0 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, - 1. 0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, - 1. 0f ) ; // Front gl . Color ( 1. 0f, 0 .0f, 0 .0f ) ; gl . Vertex ( 1. 0f, 1 .0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, 1 .0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, 1 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, 1 .0f ) ; // Back gl . Color ( 1. 0f, 1 .0f, 0 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, - 1. 0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, - 1. 0f ) ; gl . Vertex ( - 1. 0f, 1 .0f, - 1. 0f ) ; gl . Vertex ( 1. 0f, 1 .0f, - 1. 0f ) ; // Left gl . Color ( 0. 0f, 0 .0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, 1 .0f, 1 .0f ) ; gl . Vertex ( - 1. 0f, 1 .0f, - 1. 0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, - 1. 0f ) ; gl . Vertex ( - 1. 0f, - 1. 0f, 1 .0f ) ; // Right gl . Color ( 1. 0f, 0 .0f, 1 .0f ) ; gl . Vertex ( 1. 0f, 1 .0f, - 1. 0f ) ; gl . Vertex ( 1. 0f, 1 .0f, 1 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, 1 .0f ) ; gl . Vertex ( 1. 0f, - 1. 0f, - 1. 0f ) ; gl . End ( ) ; // Контроль полной отрисовки следующего изображения gl . Flush ( ) ; // Меняем угол поворота rquad -= 3 .0f ; } } }

Получим такую анимацию:

3. Совместное вращение

Из приведенных примеров становится ясно, что вращение - достаточно легкая тема, особенно если реализовывать это с помощью технологии OpenGL. Для того, чтобы получить справа ту же вращающуюся пирамиду и тот же куб, нам необходимо скомпоновать примеры и отдельно задать координаты пера.

... // Пирамида. Очищаем матрицу. Сдвигаем перо влево от центра и вглубь gl . LoadIdentity ( ) ; Translate ( -1 .5f, 0 .0f, - 5. 0f ) ; ... // Куб. Очищаем матрицу. Сдвигаем перо вправо от центра и вглубь gl . LoadIdentity ( ) ; Translate ( 1 .5f, 0 .0f, - 5. 0f ) ; ... gl . End ( ) ;

Для получения анимации просто надо просто скачать проект и запустить.

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

rss