Навигация
Главная
Поиск
Форум
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
21 ошибка прогр... 65535
HACK F.A.Q 65535
Бип из системно... 65535
Гостевая книга ... 65535
Invision Power ... 65535
Пример работы с... 65535
Содержание сайт... 65535
ТЕХНОЛОГИИ ДОСТ... 65535
Организация зап... 65535
Вызов хранимых ... 65535
Создание отчето... 65535
Имитационное мо... 65535
Программируемая... 65535
Эмулятор микроп... 65535
Подключение Mic... 65535
Создание потоко... 65535
Приложение «Про... 65535
Оператор выбора... 65535
Реклама
Видеокамеры от российского производителя
Сейчас на сайте
Гостей: 19
На сайте нет зарегистрированных пользователей

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

Моделирование процесса обработки заданий пакетным режимом работы с квант...
Лабораторная работа по динамическим спискам на Turbo Pascal (удаление ду...
База данных - рабочее место кассира на Delphi + бд Access

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 October 25 2008 11:37:32 · 40 Комментариев · 65535 Прочтений · Для печати

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


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

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


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


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


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


подключить opengl.pas
Just JK February 07 2011 19:46:57
подскажи как, а то у меня не получается ошибку даёт
Kest February 07 2011 19:57:33
в uses добавь opengl
Just JK February 07 2011 20:22:48
блин, затупил))) сенк, всё работает норм)
Даниил March 17 2011 17:12:24
Всё получилось, только ящик лево вращается(касит)
Ilyos Talent2011 Uzbekistan March 25 2011 20: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 May 07 2011 06:46:42
Спасибо за статью!
узнал много нового)
Arhi2med May 09 2011 20: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 May 19 2011 05:58:28
У меня ругается на DC. Что это такое и в чё может быть ошибка?Пробовал на Delphi 7 и 2005. Ругается на обоихsmiley
Kest May 19 2011 08:06:38
Serg, перед использованием переменную нужно объявить:

var dc:hdc;


Irina May 24 2011 13:38:14
Чтобы был цвет, нужно добавить
glEnable(GL_COLOR_MATERIAL);
Ну, а потом можно и glColor3f использовать.
А автору статьи огромнейшее спасибо! И за статью, и за ссылку на книгу!
Oleg July 07 2011 05:51:40
Народ подскажите!!! запускаетмя без ошибок, но ничего не строит, что это может быть???
Лео July 21 2011 22:07:34
Скиньте исходники!
EXT July 27 2011 14:43:31
чтото не выходит подскажите плз
в строке SetPixelFormat(hdc, nPixelFormat, @pfd); говорит что слишком много параметров.
smiley
Pipman October 30 2011 08:03:06
Сам код нормальный, у мну все строит, хотя ОпенЖЛ первый раз юзал, сначала просто код вставлял в нужные процедуры
лолец February 14 2012 18:59:25
не забываем вставить FormPaint(Timer1); в конец этой процедуры Tform1.Timer1Timer(Sender: TObject); тогда всё запашет.
Vova August 24 2012 19:11:27
Не все переменные объявили в примере.
var dc:hdc; - то исправил. Но а на HRc также ругается. Дорабатывать надо, ребята. если публикуете
Basilcat November 13 2013 11: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 November 13 2013 11: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 November 13 2013 11: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...
Шаблон для новост...

Случайные загрузки
Основы Delphi. Пр...
Обучение Borland ...
Delphi. Учимся на...
AntiRus
начисление процен...
Панель статистики...
Таймер и секундомер
Tetris 2002
C++ Builder: Книг...
Halcyon
Animation Effect ...
Советы от Даниилы...
Win-Prolog 3.618
Дешифратор содерж...
Современное проек...
Rss Parser
Экспорт базы данн...
Переработанный пл...
Язык программиров...
Drag&Drop

Топ загрузок
Приложение Клие... 100793
Delphi 7 Enterp... 98016
Converter AMR<-... 20298
GPSS World Stud... 17059
Borland C++Buil... 14238
Borland Delphi ... 10373
Turbo Pascal fo... 7390
Калькулятор [Ис... 6080
Visual Studio 2... 5228
Microsoft SQL S... 3674
Случайные статьи
Поэтому информация...
Глава 11. Как э...
В Windows 2000 Ser...
Добавление кода дл...
Как играть в казин...
Схема двухступенч...
Как правильно вест...
744Определение пол...
безопасные динамич...
Случайные объекты
Когда заказ сделан...
Чего мы хотим от п...
Фаза исследования
Использование комп...
Зонтпакер
Программирование: ...
Загрузка кода с пл...
МОДЕЛЬ С АКТИВНОЙ ...
Разновидности комп...
Здравый смысл
РАБОТА С ГРАФИКОЙ ...
Содержание
Стеки на связанных...
Структура программы
Закрепление материала
Статистика



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


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