Навигация
Главная
Поиск
Форум
FAQ's
Ссылки
Карта сайта
Чат программистов

Статьи
-Delphi
-C/C++
-Turbo Pascal
-Assembler
-Java/JS
-PHP
-Perl
-DHTML
-Prolog
-GPSS
-Сайтостроительство
-CMS: PHP Fusion
-Инвестирование

Файлы
-Для программистов
-Компонеты для Delphi
-Исходники на Delphi
-Исходники на C/C++
-Книги по Delphi
-Книги по С/С++
-Книги по JAVA/JS
-Книги по Basic/VB/.NET
-Книги по PHP/MySQL
-Книги по Assembler
-PHP Fusion MOD'ы
-by Kest
Professional Download System
Реклама
Услуги

Автоматическое добавление статей на сайты на Wordpress, Joomla, DLE
Заказать продвижение сайта
Программа для рисования блок-схем
Инженерный калькулятор онлайн
Таблица сложения онлайн
Популярные статьи
OpenGL и Delphi... 65535
Бип из системно... 65535
Пример работы с... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
21 ошибка прогр... 65535
Гостевая книга ... 65535
Форум на вашем ... 65535
HACK F.A.Q 65535
Содержание сайт... 65535
Invision Power ... 65535
Имитационное мо... 65535
Программируемая... 65535
Оператор выбора... 65535
Реклама
Сейчас на сайте
Гостей: 2
На сайте нет зарегистрированных пользователей

Пользователей: 13,277
новичок: goaeoz
Новости
Реклама
Выполняем курсовые и лабораторные по разным языкам программирования
Подробнее - курсовые и лабораторные на заказ
Delphi, Turbo Pascal, Assembler, C, C++, C#, Visual Basic, Java, GPSS, Prolog, 3D MAX, Компас 3D
Заказать программу для Windows Mobile, Symbian

Моделирование круглосуточного интернет кафе на GPSS + Отчет
Программа тестирования (тест) - вступительные экзамены (математика, физи...
Принадлежит ли точка пересечению двух окружностей на Turbo Pascal + Отче...

OpenGL и Delphi (3D графика)
Cейчас уже ни кого не удивляет разнообразие игр с 3-х мерной графикой. За относительно небольшие сроки программисты умудряются создать небольшой виртуальный мир. Если посмотреть в его корень, то станут видны сложные математические формулы. Лет 10-15 назад, используя их, программисты с нуля разрабатывали 3-х мерные миры таких игр, как Wolf 3d, Rise Of the Triad, Doom. Тоже самое происходило и с CAD-ситемами для создания моделей будущих механизмов и машин. Сегодня же для этих целей используются готовые программные средства, берущие на себя заботы о прорисовке графики. Наверное, нет человека, который бы не слышал таких названий, как Direct3D, OpenGL. Они являются результатом сотрудничества крупных омпьютерных компаний.

OpenGL появилась и сформировалась как стандарт 3-х мерной графики в 1992 г. Однако, разработка ее велась еще с 1982. Формированием этого стандарта занимались также такие фирмы, как: Microsoft, IBM сorporation, Sun Microsystems, Inc., Digital Equipment Corporation (DEC), Hewlett-Packard Corporation, Intel Corporation и др. Результат - это OpenGL - стандартная библиотека для многих 32-разрядных операционных систем (Windows, Linux в том числе), в отличие от Direct3D, которая характерна только для Windows. OpenGl содержит в себе более 100 . Они находятся в opengl32.dll (Windowssystem) и в расширении glu32.dll.

 

Чтобы вы могли хотябы немного (:-) представить их возможности, вспомните такие игры как: Quake 3, Return To the Castle Of Wolf, а также хранитель экрана в Windows под названием "Объемный текст" :-).

 

OpenGl можно использовать с разными языками программирования, поддерживающими работу с . Но во многих уже есть поддержка OpenGl, "ограждающая" программиста от непосредственой работы с функциями и процедурами из DLL. Одним из таких языков программирования является , использующийся в среде Delphi. Да, да! Именно Delphi. Этот факт еще раз доказывает то, что в Delphi можно создавать не только скучные базы данных, но и полноценные мультимедийные приложения (игры, демо-програмки). Да и вообще в Delphi столько разных возможностей! Но сегодня поговорим об использовании OpenGl.

 

Delphi и OpenGl

 

Начиная с 3-й версии в комплекте Delphi поставляется заголовочный файл, содержащий описания процедур и функций, содержащихся в opengl32.dll. А также файл помощи с описанием типов, процедур и функций (далее команд). В 3-й версии хэлп очень уж облегченный и почти полностью "стянутый" с СИ, в 5-й версии уже наблюдаются улучшения. Для того, чтобы использовать OpenGL в Delphi-проекте нужно дописать к списку подключаемых модулей opengl. После этого по любой ее команде можно получить подсказку или помощь обычным в Delphi способом. Для использования OpenGL вовсе не обязательно иметь 3d аксселератор (но не помешало бы). При работе с простенькими сценами и для изучения основ вполне достаточно даже S3 Trio с 1 мб. Сервер OpenGL перед началом работы определяет, на каком оборудовании его пользуют и, в соответствие с этим, подбирает оптимальные настройки. Для этого программист в своей программе должен сделать установку формата пикселя, которому соответствует тип TPixelFormatDescriptor. При установке формата пикселя можно задавать различные флаги, влияющие на вывод изображения. Например, если вы используете анимацию, то без установки флага PFD_DOUBLEBUFFER никак не обойтись. Он устанавливает режим двойной буферизации - изображение сначала рисуется в памяти (в буфере), а потом выводится на экран для устранения мерцания. Следует также отметить, что OpenGl является промежуточным звеном между программой и устройством вывода. Т.е. ему надо сообщать, куда будет производиться вывод. Для этого используется контекст устройства и контекст воспроизведения. Первому соответствует свойство canvas.handle формы или др. Для второго - в OpenGl существует специальный тип HGLRC (Handle openGL Rendering Context) - ссылка на контекст воспроизведения.

 

Команды и типы OpenGl

 

Мультиплатформенность OpenGl обусловлена наличием ее собственных типов данных. Начинаются они с префикса GL и приведены в заголовочном файле Delphi - opengl.pas. Многим соответствуют стандартные типы Delphi (например, GLfloat соответствует типу Single - числу с плавающей точкой). Команды OpenGl начинаются тоже с префикса GL, после которого идет обозначение действия команды. В окончании определяется количество требуемых аргументов и их тип. Например, glColor3f - команда OpenGl для установки цвета, использующая 3 аргумента - числа с плавающей точкой (f - от слова float). Если в окончании присутсвует симовол v (пример, 3fv), это значит, что в качестве аргумента будет использоваться массив (окончание 3fv указывает, что аргумент - массив 3-х чисел с плавающей точкой). Практически все команды для рисования размещаются в специальных программных скобках glBegin и glEnd. Они не имеют ничего общего с паскалевским begin, end. У glBegin есть аргумент, которым является константа, определяющая рисуемый далее (до glEnd) графический примитив. Например, между glbegin и glEnd есть команды, задающие координаты вершин примитива. Если аргументом glBegin является, к примеру, константа gl_quads, то построится прямоугольник на задаваемых далее вершинах, если gl_points - просто точки с координатами вершин и т.п. Рекомендуется использовать тип аргументов - GlFloat, но можно работать и с другими. Если вы используете GlFloat, то обратите внимание на то, что вывод будет осуществляться в область от -1 до +1 по x и по y. Так (-1,-1) - координата верхнего левого угла области вывода, а (-0.99,-1) - точка где-то рядом с ним. При задании цвета, 0 - минимальное значение его составляющей (rgb), а 1 - максимальное (вроде, как 255), 0.5 - среднее.


Чтобы разобраться со всем этим на практике давайте рассмотрим простой пример. Он рисует некое кубическое подобие коробка, которое вращается и освещается источником света. Первым делом пропишем процедуру, устанавливающую формат пиксела. Она имеет такой вид:


procedure SetDCPixelFormat (hdc : HDC);

var

pfd : TPixelFormatDescriptor;

nPixelFormat : Integer;

begin

FillChar (pfd, SizeOf (pfd), 0);

pfd.dwFlags :=PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;

nPixelFormat :=ChoosePixelFormat (hdc, @pfd);

SetPixelFormat(hdc, nPixelFormat, @pfd);

end;


Здесь во флагах pfd устанавливаются PFD_SUPPORT_OPENGL или PFD_DOUBLEBUFFER - это “говорит” серверу OpenGL, что система, на которой он будет работать поддерживает работу с ним, а также, что будет использоваться двойная буферизация. Далее ChoosePixelFormat подбирает формат пикселя, а SetPixelFormat - устанавливает этот формат. В качестве аргумента в процедуру передается ссылка на контекст устройства. Далее в обработчиках событий OnCreate и OnDestroy формы напишите следующее:


procedure Tform1.FormCreate(Sender: TObject);

begin

DC := GetDC (Handle);

SetDCPixelFormat(DC);

hrc := wglCreateContext(DC);

wglMakeCurrent(DC, hrc);

glClearColor (0.0, 0.0, 0.75, 1.0);

glMatrixMode (GL_PROJECTION);

glLoadIdentity;

glFrustum (-1, 1, -1, 1, 2, 20);

glMatrixMode (GL_MODELVIEW);

glLoadIdentity;

glTranslatef(0.0, 0.0, -6.0);

end;

procedure Tform1.FormDestroy(Sender: TObject);

begin

wglMakeCurrent(0, 0);

wglDeleteContext(hrc);

ReleaseDC (Handle, DC);

DeleteDC (DC);

end;


В первом случае при создании формы получаем GetDC контекст устройства (в данном случае формы), устанавливаем формат пикстела, с помощью wglCreateContext создаем контекст воспроизведения и делаем его основным (можно использовать несколько контекстов). Переменная hrc имеет тип HGLRC, а DC - HDC. Рекомендуется определять их в разделе private. Затем определяем цвет фона и устанавливаем матрицу преобразования координат для построения объемного изображения. glTranslatef "сдвигает в глубину" рисуемый далее объект.

Теперь создайте на форме кнопку - для запуска анимации. А в ее обработчике события OnCLick наберите такой текст:


procedure Tform1.Button1Click(Sender: TObject);

begin

glEnable (GL_LIGHTING);

glEnable (GL_LIGHT0);

glEnable (GL_DEPTH_TEST);

timer1.enabled:=true;

end;


glEnable позволяет включать разные опции. В данном случае - использование источников света.

 

Далее этой же командой включаем источник света GL_LIGHT0. Их может быть несколько, но в данном случае ограничимся одним. glEnable (GL_DEPTH_TEST) - включает режим проверки глубины изображения. Позднее попробуйте ее убрать - сразу поймете, что к чему.

 

Поместите на форму таймер, установите его интервал 100 и enable=false, а обработчик его события приведите к таком виду:


procedure Tform1.Timer1Timer(Sender: TObject);

begin

glRotatef(1.0, 1.0, 1.0, 1.0);

glRotatef(1.0, 1.0, 1.0, 0.0);

glRotatef(1.0, 1.0, 1.0, 1.0);

SwapBuffers(DC);

InvalidateRect(Handle, nil, False);

end;


На каждый тик таймера будет происходить поворот командой glRotatef на угол 1 (первый аргумент).

 

Затем SwapBuffers(DC) картинку из памяти отобразит на форме. Для перерисовки формы лучше использовать функцию API InvalidateRect - это быстрее, чем repaint. Теперь осталось последнее - задать, что же будет вырисовываться. В обработчике события формы Onpaint каждый раз рисуется одна и та же картинка, но так как по таймеру происходит поворот координатных осей, создается эффект анимации и вращения именно объекта. В OpenGl есть также возможность изменять точку наблюдателя - glLookAt.


procedure Tform1.FormPaint(Sender: TObject);

begin

glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);

glNormal3f(0.0, 0.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(-1.0, -1.0, 1.0);

glVertex3f(1.0, -1.0, 1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(-1.0, 0.0, 0.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(-1.0, 1.0, -1.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, 1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(0.0, 1.0, 0.0);

glVertex3f(-1.0, 1.0, -1.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, -1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(1.0, 0.0, -1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(1.0, -1.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, -1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(0.0, 0.0, -1.0);

glVertex3f(1.0, -1.0, 1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, 1.0);

glEnd;

end;


GlClear - очищает буфер. А далее заданием коодинат вершин (glVertex) строим стороны куба. glNormal - задает так называемый вектор нормали, требующийся для корректного изменения цвета объекта при освещении. Теперь все готово - можете запускать и любоваться сиим творением.

Данная статья только знакомит с некоторыми основами OpenGL, но не рассматривает многочисленных нюансов и возможностей этой замечательной библиотеки, т.к. для это потребовалось бы несколько десятков журналов, посвященных только ей. Да и вообще, зачем превращать замечательный журнал в узкоспециализированное учебное поссобие - ведь информации по OpenGL достаточно и в Интернет и на книжных рынках. Могу посоветовать книгу , М.Краснов, 2000 г. издательство bhv. Вообще, со слов специалистов, OpenGL более легкий в изучении, чем Direct3D, а по мощности и возможностям не уступает. Причина, по которой многие используют Direct3d в основном заключается в том, что в придачу к нему есть еще библиотеки для работы со звуком, музыкой, сеткой, вводом/выводом. Но вы же видели, что создают парни из Id Software? На мой взгляд, (без лишних слов) OpenGL - rulez! Так, что изучайте. Пригодится не только для создания игр, но и для серьёзных вещей, вроде моделирования работы различных механизмов и т.п.

Опубликовал Kest Октябрь 25 2008 15:37:32 · 40 Комментариев · 65535 Прочтений · Для печати

• Не нашли ответ на свой вопрос? Тогда задайте вопрос в комментариях или на форуме! •


Комментарии
Admer Март 30 2009 19:58:34
В Delphi 7 этот пример у меня не работает, выдает обычное окно с серым фоном, который после нажатия на кнопку меняется на черный. И ничего больше этого черного окна у меня нет.
А статья написана хорошо, читать приятно и информации много, . и тем более обидно что пример не работает. Надеюсь это не так и задумано ?
Kest Март 30 2009 23:24:31
Что то ты неправильно сделал.. У меня все получилосьsmiley. Вот скрин:

DeadDDante Апрель 08 2009 15:53:37
Спс! Очень актуально в предверии курсовой))
fantaradist Март 18 2010 12:45:07
3D анимация - это круто smiley
grim Апрель 04 2010 12:12:57
а у меня почему то без граней получился(
Tim Kruz Июнь 28 2010 21:43:37
У меня тоже чёрное окно и всё. smiley
Хотя я у меня Дэлфи 7 и 2D OpenGL работает нормально.
Kest Июнь 28 2010 22:42:59
Tim Kruz
У меня тоже чёрное окно и всё.
Хотя я у меня Дэлфи 7 и 2D OpenGL работает нормально.


Попробуй установить эту - codingrus.ru/infusions/pro_download_panel/download.php?did=70
Alex Июль 04 2010 13:55:13
С OpenGL работаю в-первые, вообще в Делфи мало работалsmiley пример получилсяsmiley, но понимаю что полноценные проги в 3D пока очень сложноваты для меня
дупар Август 06 2010 11:51:40
Таки не понял что кнопка то делает smiley
Lexa Октябрь 04 2010 01:38:10
Подскажите пожалуйста какие компоненты использовать для Open Gl
Kest Октябрь 04 2010 10:28:03
Lexa
Подскажите пожалуйста какие компоненты использовать для Open Gl


Не нужны компоненты
Раита Ноябрь 11 2010 15:48:37
Не знаете, где скачать нормальный TurboBorlandC++
сергей Ноябрь 26 2010 13:59:48
а можете выложить исходник?
Kest Ноябрь 26 2010 16:08:32
сергей
а можете выложить исходник?


в том и смысл, что нужно сделать самому
сергей Ноябрь 27 2010 15:14:16
эх...печально...у меня не получается
П****н Декабрь 21 2010 16:47:48
Спс. автору, всё работает отлично =) Правда этот самый куб сжирает 10 мегабайт ОЗУ ))
slavyan_malinin Декабрь 25 2010 13:35:54
Здесь ошибочка: glNormal3f(1.0, 0.0, -1.0); Нормаль должна иметь направление glNormal3f(1.0, 0.0, 0.0); А еще, чтобы не коробка, а кубик получился, надо шестую грань просто добавить.
Klesh Январь 21 2011 17:45:37
Всё просто супер.smiley
Я бы хотел спросить как поменять положение источника освещения и его цвет.
RaDen Январь 28 2011 09:39:36
Всё работает, но не получается изменить цвет примитива, как-будто glColor3f вообще нет... Что может быть не так? Что-то надо включить/настроить/изменить? smiley
Just JK Февраль 07 2011 12:51:19
у меня делфи 7 ентерпрайс ругается на все операторы GL((( как это исправить?
Kest Февраль 07 2011 21:21:38
Just JK
у меня делфи 7 ентерпрайс ругается на все операторы GL((( как это исправить?


подключить opengl.pas
Just JK Февраль 07 2011 22:46:57
подскажи как, а то у меня не получается ошибку даёт
Kest Февраль 07 2011 22:57:33
в uses добавь opengl
Just JK Февраль 07 2011 23:22:48
блин, затупил))) сенк, всё работает норм)
Даниил Март 17 2011 20:12:24
Всё получилось, только ящик лево вращается(касит)
Ilyos Talent2011 Uzbekistan Март 25 2011 23:49:44
Salom Sizlarning saytingiz juda yaxshi ishlab chiqilgan. Ayniqsa yuklanish jarayonlari jida ham yaxshi. Aniq va sodda ishlanganiga qaramay men o`zim uchun kerakli juda ko`p ma`lumotlarni topdim. Yana bir narsa. Delphi ning 3ds Max kabi dasturlar bilan qanday ulanishini va unga kerakli barcha Kompanentalarni birinchi saxifada chiqarsangiz.smiley
asp1k Май 07 2011 10:46:42
Спасибо за статью!
узнал много нового)
Arhi2med Май 10 2011 00:44:05
Огромное студенческое спасибо, за доступно поданный материал,
добавил шестую грань все оказалось до тривиальности просто.
glBegin(GL_QUADS);
glNormal3f(0.0,0.0,-1.0);
glVertex3f(-1.0,-1.0,-1.0);
glVertex3f(1.0,-1.0,-1.0);
glVertex3f(1.0,1.0,-1.0);
glVertex3f(-1.0,1.0,-1.0);
glEnd;
Хотелось -бы,чтоб тему Open GL продолжили.
Спасибо!!!!!!!!
Serg Май 19 2011 09:58:28
У меня ругается на DC. Что это такое и в чё может быть ошибка?Пробовал на Delphi 7 и 2005. Ругается на обоихsmiley
Kest Май 19 2011 12:06:38
Serg, перед использованием переменную нужно объявить:

var dc:hdc;


Irina Май 24 2011 17:38:14
Чтобы был цвет, нужно добавить
glEnable(GL_COLOR_MATERIAL);
Ну, а потом можно и glColor3f использовать.
А автору статьи огромнейшее спасибо! И за статью, и за ссылку на книгу!
Oleg Июль 07 2011 09:51:40
Народ подскажите!!! запускаетмя без ошибок, но ничего не строит, что это может быть???
Лео Июль 22 2011 02:07:34
Скиньте исходники!
EXT Июль 27 2011 18:43:31
чтото не выходит подскажите плз
в строке SetPixelFormat(hdc, nPixelFormat, @pfd); говорит что слишком много параметров.
smiley
Pipman Октябрь 30 2011 12:03:06
Сам код нормальный, у мну все строит, хотя ОпенЖЛ первый раз юзал, сначала просто код вставлял в нужные процедуры
лолец Февраль 14 2012 22:59:25
не забываем вставить FormPaint(Timer1); в конец этой процедуры Tform1.Timer1Timer(Sender: TObject); тогда всё запашет.
Vova Август 24 2012 23:11:27
Не все переменные объявили в примере.
var dc:hdc; - то исправил. Но а на HRc также ругается. Дорабатывать надо, ребята. если публикуете
Basilcat Ноябрь 13 2013 15:44:00
Вот вам решение прямого пересечения трубы большего диаметра R1 с трубой меньшего диаметра R0:
Вращение - движение мыщью X+ , X-. Изменентие координаты вращения - Click левой кнопкой мыши.

unit Unit_Algoritm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Spin, Grids, OpenGL, ExtCtrls;



type
TPointM=record
x,y,z:double;
end;

TPoint_M=array[1..3599] of TPointM;


TForm1 = class(TForm)
SpinEdit_R0: TSpinEdit;
SpinEdit_R1: TSpinEdit;
StringGrid_Cilinder: TStringGrid;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
X_,Y_,R0,R1,X,Y,Z,alpha,Lx,beta,dX,dY,dZ:double;
DrawBuffer : TBitMap;
Points3D: TPoint_M;
Direct:boolean;
tx : GLfloat; // tx âåùåñòâåííîãî òèïà
ty : GLfloat; // ty âåùåñòâåííîãî òèïà
tz : GLfloat; // tz âåùåñòâåííîãî òèïà
DC:HDC;
HRC:HGLRC;
Points3D_YZ: TPoint_M;
Points3D_XY: TPoint_M;
Axis:integer;
X_MouseOld,Y_MouseOld:integer;
procedure ClearBuffer;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Math;

{$R *.dfm}


procedure SetDCPixelFormat (hdc : HDC);

var

pfd : TPixelFormatDescriptor;

nPixelFormat : Integer;

begin

FillChar (pfd, SizeOf (pfd), 0);

pfd.dwFlags :=PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;

nPixelFormat :=ChoosePixelFormat (hdc, @pfd);

SetPixelFormat(hdc, nPixelFormat, @pfd);

end;

procedure TForm1.ClearBuffer;
begin
DrawBuffer.Canvas.Pen.Color := clBlack;
DrawBuffer.Canvas.Brush.Color := clBtnFace ;
DrawBuffer.Canvas.Rectangle(0, 0, ClientWidth, ClientHeight);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
i,J:integer;
Cosn, Sinn:double;
row:integer;
DX_Pred, DY_Pred, DZ_Pred:double;
begin

row:=1;
R0:=SpinEdit_R0.Value;
R1:=SpinEdit_R1.Value;
DX_Pred:=R0;
DY_Pred:=0;
DZ_Pred:=R1;
for i:=1 to 3599 do // 0.1 ãðàäóñà
begin
StringGrid_Cilinder.RowCount:=row;
alpha:=(Pi/180)*i;
Sinn:=Sin(alpha/10);
Y:=R0*Sinn;
Cosn:=Cos(alpha/10);
X:=R0*Cosn;
Z:=SQRT(X*X+(R1*R1-R0*R0));
beta:=arccos(Z/R1);
Lx:=R1*beta;
dX:=X-DX_Pred;
dY:=Y-DY_Pred;
dZ:=Z-DZ_Pred;
DX_Pred:=X;
DY_Pred:=Y;
DZ_Pred:=Z;
StringGrid_Cilinder.Cells[0,i]:=IntToStr(I);
StringGrid_Cilinder.Cells[1,i]:=FloatToStrF(X,ffFixed,12,2);
StringGrid_Cilinder.Cells[2,i]:=FloatToStrF(Y,ffFixed,12,2);
StringGrid_Cilinder.Cells[3,i]:=FloatToStrF(Z,ffFixed,12,2);
StringGrid_Cilinder.Cells[4,i]:=FloatToStrF(dX,ffFixed,12,2);
StringGrid_Cilinder.Cells[5,i]:=FloatToStrF(dY,ffFixed,12,2);
StringGrid_Cilinder.Cells[6,i]:=FloatToStrF(dZ,ffFixed,12,2);
StringGrid_Cilinder.Cells[7,i]:=FloatToStrF(((alpha*180/Pi)/10),ffFixed,12,2);
StringGrid_Cilinder.Cells[8,i]:=FloatToStrF((beta*180/Pi),ffFixed,12,2);
StringGrid_Cilinder.Cells[9,i]:=FloatToStrF(Lx,ffFixed,12,2);
Inc(Row);

Points3D[I].X := X;
Points3D[I].Y := Y;
Points3D[I].Z := Z;

Points3D_XY[I].X := X;
Points3D_XY[I].Y := Y;
Points3D_XY[I].Z := 0;

Points3D_YZ[I].X := 0;
Points3D_YZ[I].Y := Y;
Points3D_YZ[I].Z := Z;

end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i:integer;
begin
Axis:=1;
i:=0;
StringGrid_Cilinder.Cells[0,i]:='¹';
StringGrid_Cilinder.Cells[1,i]:='X';
StringGrid_Cilinder.Cells[2,i]:='Y';
StringGrid_Cilinder.Cells[3,i]:='Z';
StringGrid_Cilinder.Cells[4,i]:='dX';
StringGrid_Cilinder.Cells[5,i]:='dY';
StringGrid_Cilinder.Cells[6,i]:='dZ';
StringGrid_Cilinder.Cells[7,i]:='AlfaXY';
StringGrid_Cilinder.Cells[8,i]:='BetaYZ';
StringGrid_Cilinder.Cells[9,i]:='Lx';

DC := GetDC (Handle);

SetDCPixelFormat(DC);

hrc := wglCreateContext(DC);

wglMakeCurrent(DC, hrc);

glClearColor (0.0, 0.0, 0.0, 0.0);

glMatrixMode (GL_PROJECTION);

glLoadIdentity;

glFrustum (-1, 1, -1, 1, 2, 20);

glMatrixMode (GL_MODELVIEW);

glLoadIdentity;

glTranslatef(0.0, 0.0, -6.0);

end;

procedure Tform1.FormDestroy(Sender: TObject);

begin

wglMakeCurrent(0, 0);

wglDeleteContext(hrc);

ReleaseDC (Handle, DC);

DeleteDC (DC);


end;


procedure TForm1.Button2Click(Sender: TObject);
begin
{glEnable (GL_LIGHTING);

glEnable (GL_LIGHT0);

glEnable (GL_DEPTH_TEST);

timer1.enabled:=true;
}
end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin

{glRotatef(1.0, 1.0, 1.0, 1.0);

glRotatef(1.0, 1.0, 1.0, 0.0);

glRotatef(1.0, 1.0, 1.0, 1.0);
}
//glRotatef(1.0, 1, 1, 1);
//glRotatef(1.0, 1, 0, 0);
//glRotatef(1.0, 0, 0, 1);


SwapBuffers(DC);

InvalidateRect(Handle, nil, False);
end;

procedure TForm1.FormPaint(Sender: TObject);
var
i:integer;
X_,Y_,Z_:double;
X_1,Y_1,Z_1:double;

X_XY,Y_XY,Z_XY:double;
X_1XY,Y_1XY,Z_1XY:double;

X_YZ,Y_YZ,Z_YZ:double;
X_1YZ,Y_1YZ,Z_1YZ:double;


begin
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);
for i:=2 to 3599 do
begin
X_:=Points3D[i].x/400;
Y_:=Points3D[i].y/400;
Z_:=Points3D[i].z/400;

X_1:=Points3D[i-1].x/400;
Y_1:=Points3D[i-1].y/400;
Z_1:=Points3D[i-1].z/400;

//************************ ðîçîâàÿ äóãà YZ

glColor3f (1.0, 0.0, 1.0);
X_YZ:=Points3D_YZ[i].x/400;
Y_YZ:=Points3D_YZ[i].y/400;
Z_YZ:=Points3D_YZ[i].z/400;

X_1YZ:=Points3D_YZ[i-1].x/400;
Y_1YZ:=Points3D_YZ[i-1].y/400;
Z_1YZ:=Points3D_YZ[i-1].z/400;

if ((i>1) and (i<=900)) or ((i>2700) and (i<=3599)) then
begin
glVertex3f(X_1,Y_1YZ,Z_1YZ);
glVertex3d(X_,Y_YZ,Z_YZ);
glVertex3d(2,Y_YZ,Z_YZ);
glVertex3f(2,Y_1YZ,Z_1YZ);



glColor3f (0.4, 0.0, 0.4);
glVertex3f(X_1,Y_1YZ+0.05,Z_1YZ+0.05);
glVertex3d(X_,Y_YZ+0.05,Z_YZ+0.05);
glVertex3d(2,Y_YZ+0.05,Z_YZ+0.05);
glVertex3f(2,Y_1YZ+0.05,Z_1YZ+0.05);

end;


//******************************** ïîëîñêà ïåðåñå÷åíèÿ öèëèíäðîâ XYZ
glColor3f (0.0, 0.0, 1.0);
glNormal3f(1.0, 0.0, 0.0);
glVertex3f(X_1,Y_1,Z_1);
glVertex3d(X_,Y_,Z_);
glVertex3d(X_,Y_,Z_-0.02);
glVertex3f(X_1,Y_1,Z_1-0.02);

//************************ çåë¸íûé öèëèíäð XY R0 ïðîðåçàþùèé öèëèíäð R1

glColor3f (0.0, 1.0, 1.0);
X_XY:=Points3D_XY[i].x/400;
Y_XY:=Points3D_XY[i].y/400;
Z_XY:=Points3D_XY[i].z/400;

X_1XY:=Points3D_XY[i-1].x/400;
Y_1XY:=Points3D_XY[i-1].y/400;
Z_1XY:=Points3D_XY[i-1].z/400;

glVertex3f(X_1XY,Y_1XY,Z_1);
glVertex3d(X_XY,Y_XY,Z_1);
glVertex3d(X_XY,Y_XY,2);
glVertex3f(X_1XY,Y_1XY,2);

glColor3f (0.0, 0.7, 0.7);
glVertex3f(X_1XY-0.02,Y_1XY-0.02,Z_1);
glVertex3d(X_XY-0.02,Y_XY-0.02,Z_1);
glVertex3d(X_XY-0.02,Y_XY-0.02,2);
glVertex3f(X_1XY-0.02,Y_1XY-0.02,2);




end;
glEnd;

end;


procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
decret:integer;
begin
if X_MouseOld>X then
decret:=1
else
decret:=-1;

if Axis=1 then
glRotatef(decret, 1, 0, 0)
else
if Axis=2 then
glRotatef(decret, 0, 1, 0)
else
glRotatef(decret, 0, 0, 1);
X_MouseOld:=X;

end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Inc(Axis);
if Axis>3 then
Axis:=1;
end;

end.
:D
Basilcat Ноябрь 13 2013 15:48:28
Sorry, Form as Text:

object Form1: TForm1
Left = -18
Top = -10
Width = 1283
Height = 989
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
OnMouseDown = FormMouseDown
OnMouseMove = FormMouseMove
OnPaint = FormPaint
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 202
Top = 914
Width = 24
Height = 20
Caption = 'R0'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
end
object Label2: TLabel
Left = 362
Top = 914
Width = 24
Height = 20
Caption = 'R1'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -16
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
end
object SpinEdit_R0: TSpinEdit
Left = 160
Top = 936
Width = 121
Height = 22
MaxValue = 0
MinValue = 0
TabOrder = 0
Value = 400
end
object SpinEdit_R1: TSpinEdit
Left = 320
Top = 936
Width = 121
Height = 22
MaxValue = 0
MinValue = 0
TabOrder = 1
Value = 500
end
object StringGrid_Cilinder: TStringGrid
Left = 65
Top = 808
Width = 1016
Height = 89
ColCount = 10
DefaultColWidth = 150
FixedCols = 0
RowCount = 3
TabOrder = 2
ColWidths = (
49
105
122
128
95
96
94
104
92
93)
end
object Button1: TButton
Left = 560
Top = 904
Width = 137
Height = 41
Caption = 'ÐÀÑרÒ'
TabOrder = 3
OnClick = Button1Click
end
object Button2: TButton
Left = 848
Top = 920
Width = 75
Height = 25
Caption = 'Button2'
TabOrder = 4
OnClick = Button2Click
end
object Timer1: TTimer
Interval = 100
OnTimer = Timer1Timer
Left = 624
Top = 240
end
end:p
Basilcat Ноябрь 13 2013 15:53:50
А если захотите чтобы труба входила под углом к оси цилиндра YZ, и углом к цилиндру YZ (со стороны оси X) и ещё со смещением в оси Z), то пишите на basil_cat@ukr.net. И помните R0<R1smiley.
Добавить комментарий
Имя:



smiley smiley smiley smiley smiley smiley smiley smiley smiley
Запретить смайлики в комментариях

Введите проверочный код:* =
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Отлично! Отлично! 100% [2 Голоса]
Очень хорошо Очень хорошо 0% [Нет голосов]
Хорошо Хорошо 0% [Нет голосов]
Удовлетворительно Удовлетворительно 0% [Нет голосов]
Плохо Плохо 0% [Нет голосов]
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Поделиться ссылкой
Фолловь меня в Твиттере! • Смотрите канал о путешествияхКак приготовить мидии в тайланде?
Загрузки
Новые загрузки
iChat v.7.0 Final...
iComm v.6.1 - выв...
Visual Studio 200...
CodeGear RAD Stud...
Шаблон для новост...

Случайные загрузки
Прграммирование в...
Apollovcl61
База данных фильм...
Расширенный загру...
Шаблон для новост...
Программирование ...
Язык программиров...
isoCanvas (Редакт...
Error mod
Разработка интерн...
DCMintry
Последнее загруж...
mmmJlabel
Email
Философия C++. Пр...
Шифрование по алг...
Turbo Pascal for ...
IPAddresseEdit
Система баннеро...
MiniTetris [Исход...

Топ загрузок
Приложение Клие... 100760
Delphi 7 Enterp... 97424
Converter AMR<-... 20232
GPSS World Stud... 16981
Borland C++Buil... 14153
Borland Delphi ... 10162
Turbo Pascal fo... 7350
Калькулятор [Ис... 5921
Visual Studio 2... 5194
Microsoft SQL S... 3652
Случайные статьи
Бесплатный «межгород»
ОЦЕНКА НОВЫХ ВОЗМО...
Модель включения
СМЕШИВАНИЕ МЕТАДАН...
Сол Казино
Оптимизация КАМ-вы...
Структцра программ...
Съемка по освещени...
Игровые автоматы В...
СОЗДАНИЕ SPLASH-ФО...
Invalid ordering o...
Дополнительная инф...
Как попробовать се...
Создание сайтов. И...
Коды, построенные ...
Абстрактные типы д...
Заливка надписи
убедиться, что сет...
Линейная задача
Работа с Веб-серви...
Асинхронный режим ...
Предварительная об...
Итерация - пройтис...
Добавление и удале...
на прилагаемом ком...
Статистика



Друзья сайта
Программы, игры


Полезно
В какую объединенную сеть входит классовая сеть? Суммирование маршрутов Занимают ли таблицы память маршрутизатора?