Построения гироскопа Фуко средствами OpenGL

Общие понятия о гироскопах, их классификация и применение. Механические гироскопы, свойства трехстепенного роторного гироскопа. Создание проекта "Гироскоп Фуко" средствами OpenGL и начальная настройка среды разработки. Инициализация объекта вывода и Glut.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 18.11.2013
Размер файла 491,9 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru

Размещено на http://www.allbest.ru

МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования

«Московский государственный текстильный университет

имени А.Н. Косыгина»

Кафедра информационных технологий и систем автоматизированного проектирования

Отчет

по курсовой работе

по дисциплине «Геометрическое моделирование САПР»

Выполнил: Ворожбитов А.П. гр. 45т-10

Принял: Беспалов М.Е.

Москва 2012

Содержание

1. Описание предметной области

1.1 Общие понятия о гироскопах

1.2 Классификация гироскопов

1.3 Механические гироскопы

1.4 Свойства трехстепенного роторного гироскопа

1.5 Применение

2. Описание средств разработки

2.1 Общие сведения

2.2 Набор библиотек TaoFramework

2.3 Среда разработки SharpDevelop

3. Описание программного проекта

4. Разработка программного проекта

4.1 Создание проекта и начальная настройка среды разработки

4.2 Начальная настройка формы проекта

4.3 Инициализация объекта вывода и Glut

4.4 Общие составляющие функции визуализации

4.5 Описание геометрической модели

4.6 Описание модели средствами OpenGL

4.7 Реализация управления моделью

Выводы

Список использованных источников

Приложение

1. Описание предметной области

1.1 Общие понятия о гироскопах

Гироскоп -- устройство, способное реагировать на изменение углов ориентации тела, на котором оно установлено, относительно инерциального пространства. Простейший пример гироскопа -- юла (волчок).

Термин впервые введен Жаном (Бернаром Леоном) Фуко в его докладе в 1852 году Французской Академии Наук. Доклад был посвящён способам экспериментального обнаружения вращения Земли в инерциальном пространстве. Этим и обусловлено название «гироскоп» (от др.-греч. г?спт «круг» и укпрЭщ «смотрю»).

До изобретения гироскопа человечество использовало различные методы определения направления в пространстве. Издревле люди ориентировались визуально по удалённым предметам, в частности, по Солнцу. Уже в древности появились первые приборы: отвес и уровень, основанные на гравитации. В средние века в Китае был изобретён компас, использующий магнетизм Земли. В Европе были созданы астролябия и другие приборы, основанные на положении звёзд.

Гироскоп изобрёл Иоганн Боненбергер и опубликовал описание своего изобретения в 1817 году. Однако французский математик Пуассон ещё в 1813 году упоминает Боненбергера как изобретателя этого устройства. Главной частью гироскопа Боненбергера был вращающийся массивный шар в кардановом подвесе. В 1832 году американец Уолтер Р. Джонсон придумал гироскоп с вращающимся диском. Французский учёный Лаплас рекомендовал это устройство в учебных целях. В 1852 году французский учёный Фуко усовершенствовал гироскоп и впервые использовал его как прибор, показывающий изменение направления (в данном случае -- Земли), через год после изобретения маятника Фуко, тоже основанного на сохранении вращательного момента. Именно Фуко придумал название «гироскоп». Фуко, как и Боненбергер, использовал карданов подвес. Не позже 1853 года Фессель изобрёл другой вариант подвески гироскопа.

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

Во второй половине XIX века было предложено использовать электродвигатель для разгона и поддержания вращения гироскопа. Впервые на практике гироскоп был применён в 1880-х годах инженером Обри для стабилизации курса торпеды. В XX веке гироскопы стали использоваться в самолётах, ракетах и подводных лодках вместо компаса или совместно с ним.

1.2 Классификация гироскопов

Основные типы гироскопов по количеству степеней свободы:

· двухстепенные

· трехстепенные.

Основные два типа гироскопов по принципу действия:

· механические гироскопы,

· оптические гироскопы.

1.3 Механические гироскопы

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

Впервые это свойство использовал Фуко в 1852 г. для экспериментальной демонстрации вращения Земли. Именно благодаря этой демонстрации гироскоп и получил своё название от греческих слов «вращение», «наблюдаю».

1.4 Свойства трехстепенного роторного гироскопа

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

Это свойство обусловлено возникновением так называемой кориолисовой силы. Так, при воздействии момента внешней силы гироскоп поначалу будет вращаться именно в направлении действия внешнего момента (нутационный бросок). Каждая частица гироскопа будет таким образом двигаться с переносной угловой скоростью вращения вследствие действия этого момента. Но ротор гироскопа, помимо этого, и сам вращается, поэтому каждая частица будет иметь относительную скорость. В результате возникает кориолисова сила, которая заставляет гироскоп двигаться в перпендикулярном приложенному моменту направлении, то есть прецессировать. Прецессия вызовет кориолисову силу, момент которой скомпенсирует момент внешней силы (гироскопический момент).

Гироскопический эффект вращающихся тел есть проявление коренного свойства материи -- её инерционности.

1.5 Применение

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

Чаще всего используются гироскопы, помещённые в карданов подвес. Такие гироскопы имеют 3 степени свободы, то есть он может совершать 3 независимых поворота вокруг осей АА', BB' и CC', пересекающихся в центре подвеса О, который остаётся по отношению к основанию A неподвижным.

Гироскопы, у которых центр масс совпадает с центром подвеса O, называются астатическими, в противном случае -- статическими гироскопами.

Для обеспечения вращения ротора гироскопа с высокой скоростью применяются специальные гиромоторы.

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

Гироскопы используются в виде компонентов как в системах навигации (авиагоризонт, гирокомпас, ИНС и т. п.), так и в системах ориентации и стабилизации космических аппаратов.

При использовании в гировертикали показания гироскопа должны корректироваться акселерометром (маятником), так как из за суточного вращения земли и ухода гироскопа, происходит отклонение от истиной вертикали. Кроме того, в механических гироскопах может использоваться смещение его центра масс, которое эквивалентно непосредственному воздействию маятника на гироскоп.

Задачей данной курсовой работы стоит разработка интерактивной геометрической модели трехстепенного механического роторного гироскопа Фуко, функционирующего идеализированно.

2. Описание средств разработки

2.1 Общие сведения

Для выполнения поставленной задачи в качестве средств разработки были выбраны SharpDevelop 3.0 и TaoFramework 2.1.0.

Данный выбор обусловлен тем, что эти продукты бесплатны, находятся в свободном доступе, достаточно популярны и для своего применения не требуют больших ресурсов ЭВМ.

2.2 Набор библиотек TaoFramework

Tao Framework -- это библиотека, предоставляющая разработчикам.NET и Mono доступ к возможностям популярных библиотек вроде OpenGL и SDL. В ее состав входят:

· OpenGL 2.1.0.12

· Lua 5.1.3.0

· OpenAL 1.1.0.1

· PhysFS 1.0.1.2

· FreeGLUT 2.4.0.2

· SDL 1.2.13.0

· GLFW 2.6.0.0

· ODE 0.9.0.0

· Cg 2.0.0.0

· DevIL 1.6.8.3

· FreeType 2.3.5.0

· FFmpeg 0.4.9.0

На данный момент в Windows существует два стандарта для работы с трёхмерной графикой: OpenGL, являющийся стандартом де-факто для всех графических рабочих станций, и Direct3D - стандарт, предложенный фирмой Microsoft. Далее будет рассмотрен только стандарт OpenGL

Существенным достоинством OpenGL является его широкая распространенность - он является стандартом в мире графических рабочих станций типа Sun, Silicon Graphics и др. В основу стандарта была положена библиотека IRIS GL, разработанная фирмой Silicon Graphics Inc.

OpenGL представляет собой программный интерфейс к графическому оборудованию (хотя существуют и чисто программные реализации OpenGL). Интерфейс насчитывает около 120 различных команд, которые программист использует для задания объектов и операций над ними (необходимых для написания интерактивных трёхмерны приложений).

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

OpenGL позволяет:

1. Создавать объекты из геометрических примитивов (точки, линии, грани и битовые изображения).

2. Располагать объекты в трёхмерном пространстве и выбирать способ и параметры проецирования.

3. Вычислять цвет всех объектов. Цвет может быть как явно задан, так и вычисляться с учётом источников света, параметров освещения, текстур.

4. Переводить математическое описание объектов и связанной с ними информации о цвете в изображение на экране.

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

Команды OpenGL реализованы как модель клиент-сервер. Приложение выступает в роли клиента - оно вырабатывает команды, а сервер OpenGL интерпретирует и выполняет их. Сам сервер может находиться как на том же компьютере, на котором находится и клиент, так и на другом.

Основным используемым компонентом, помимо OpenGL, в данной работе является FreeGLUT.

OpenGL Utility Toolkit (GLUT) -- библиотека утилит для приложений под OpenGL, которая в основном отвечает за системный уровень операций ввода-вывода при работе с операционной системой. Из функций можно привести следующие: создание окна, управление окном, мониторинг за вводом с клавиатуры и событий мыши. Она также включает функции для рисования ряда геометрических примитивов: куб, сфера, чайник. GLUT даже включает возможность создания несложных всплывающих меню.

GLUT был создан Марком Килгардом (Mark Kilgard), во время его работы в Silicon Graphics Inc.

Использование библиотеки GLUT преследует две цели. Во-первых, это создание кроссплатформенного кода. Во-вторых, GLUT позволяет облегчить изучение OpenGL. Чтобы начать программировать под OpenGL, используя GLUT, требуется всего страница кода. Написание аналогичных вещей на API требует несколько страниц, написанных со знанием API управления окнами операционной системы.

2.3 Среда разработки SharpDevelop

SharpDevelop (сокращенно #Develop) свободная среда разработки для языков группы Microsoft NET(C#, F#, Visual Basic.NET, Boo). Предоставляет собой интегрированный отладчик, который использует собственные библиотеки и взаимодействует с исполняющей средой.NET через COM Interop.

Возможности и особенности:

· Написана полностью на C#

· Подсветка синтаксиса для C#, IronPython, HTML, ASP, ASP.NET, VBScript, VB.NET, XML, XAML

· Визуальный редактор для форм WinForms (COM-компоненты не поддерживаются)

· Интегрированная поддержка NUnit, MbUnit и NCover

· Интегрированная поддержка анализатора сборок FxCop

· Интегрированный отладчик

· Интегрированная поддержка SVN

· Конвертор кода между языками C#, VB.NET, IronPython и Boo

· Предпросмотр документации, полученной из документирующих комментариев

· Расширяемость внешними инструментами

· Расширяемость на основе механизма Add-Ins

· Для работы требуется Microsoft.NET Framework 3.5 + Service Pack 1

· Для работы в F# требуется установить дополнение

Разработанное с использованием данных средств приложение требует для запуска небольших вычислительных и графических мощностей.

3. Описание программного проекта

гироскоп фуко opengl

Программный проект «Гироскоп Фуко» состоит из:

· исполняемого файла gyroscope.exe

· библиотек формата dll Tao.OpenGL, Tao.FreeGlut, Tao.Platform.Windows

· иконки приложения icon.ico

Проект оформлен в виде установочного файла сторонними средствами

(Smart Install Maker) для удобства установки. После установки опционально на рабочем столе создается ярлык для быстрого запуска приложения. По умолчанию проект устанавливается в системную папку Program Files.

4. Разработка программного проекта

4.1 Создание проекта и начальная настройка среды разработки

После установки среды разработки SharpDevelop и комплекта библиотек TaoFramework необходимо скопировать файлы из директории C:\Programm Files\TaoFramework\lib в директорию C:\Windows\System32.

Далее создается программный проект (Solution) в SharpDevelop, путем прохождения через цепочку основного меню File -> New -> Solution. После задания имени проекта, выбора типа необходимо подключить библиотеки и объявить их в разделе объявления заголовочных файлов.

Добавить библиотеки можно в меню Project -> Add Reference. После выбора библиотек, приведенных в разделе 3, их необходимо подключить. Подключение библиотек производится оператором using. Данные действия описаны в Листинге №1. (Так же далее в процессе описания будут представлены фрагменты программного кода, полный листинг будет представлен в приложении А).

using Tao.FreeGlut;

using Tao.OpenGl;

using Tao.Platform.Windows;

Листинг 1. Подключение библиотек проекта

4.2 Начальная настройка формы проекта

Для отображения модели необходимо разместить элемент, с помощью которого библиотеки OpenGL смогли бы вывести изображение на рабочее пространство приложения (в данном случае форму). Для этого в библиотеке Tao.Platform.Windows существует визуальный компонент simpleOpenGLControl. Необходимо разместить его на форме и в панели свойств установить свойству Dock значение Fill, чтобы компонент занял все свободное пространство формы. Этим действием задается рабочее пространство отображения модели проектом.

В описываемом проекта данный компонент имеет имя AnT.

4.3 Инициализация объекта вывода и Glut

Для инициализации компонента отображения simpleOpenGLControl используется команда <имя компонента>.InitializeContexts(). Данная команда располагается в конструкторе класса формы, и инициализирует работу компонента непосредственно после запуска приложения.

public MainForm()

{

InitializeComponent();

AnT.InitializeContexts();

}

Листинг 2. Конструктор формы

После инициализации компонента вывода необходимо инициализировать сам Glut. Выполняется это командой glutInit(). Также нужно задать режим работы компонента вывода средствами библиотеки и цвет очистки окна.

Glut.glutInit();

Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);

Gl.glClearColor(0, 0, 0, 1);

Листинг 3. Инициализация Glut и начальная настройка вывода

В параметрах инициализации GLUT_RGB означает что используется режим цветов RGB(от Red, Green, Blue - красный, зеленый, синий; компонентность цвета), GLUT_DOUBLE означает использование двойной буферизации и GLUT_DEPTH использование буфера глубины (Z-буфер).

Команда glClearColor имеет 4 параметра: полнота компонентов цветности: красного, зеленого и синего и значение прозрачности, где 1 непрозрачность, а 0 полная прозрачность.

Инициализировав Glut, необходима инициализация освещения сцена, настройка его параметров, также тест глубины и установка обработки цвета при освещении.

Gl.glEnable(Gl.GL_DEPTH_TEST);

Gl.glEnable(Gl.GL_LIGHTING);

Gl.glEnable(Gl.GL_LIGHT1);

float[] bluish = { 1f, 1f, 1f, 0.1f };

Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, bluish);

Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, bluish);

Gl.glLightModeli(Gl.GL_LIGHT_MODEL_COLOR_CONTROL, Gl.GL_SEPARATE_SPECULAR_COLOR);

Листинг 4. Настройка освещения и тест глубины

Командой glEnable включается использование какого либо параметра. В данном случае использованы GL_DEPTH_TEST - тест глубины, GL_LIGHTING - использование источников света, GL_LIGHT1 - управление источником света под номером «1». Команда glLightfv осуществляет управление источником света, где GL_LIGHT1 - источник света, GL_DIFFUSE - параметр отвечающий за цвет источника света;GL_SPECULAR - за отраженный свет, третьим аргументом идет параметр, в данном случае массив с параметрами света под именем bluish. Цвет источника света и света отражения - белый. После необходима настройка модели освещения. Команда glLightModel отвечает за выбор модели освещения, где GL_LIGHT_MODEL_COLOR_CONTROL - режим вычисление зеркального цвета отдельно от фонового и диффузного, GL_SEPARATE_SPECULAR_COLOR - отвечает за наложение вторичного цвета, состоящего из суммы всех зеркальных вкладов всех источников света. Такая модель освещения обеспечит достаточную реалистичность.

4.4 Общие составляющие функции визуализации

Функции визуализации вызывается каждый раз при отрисовке кадра динамической сцены, средствами какой либо библиотек или среды разработки. В данном случае функция вызывается средствами среды, а конкретно объектом Timer.

Она состоит из:

· описания параметров вывода через визуальный компонент

· описания перспективы

· описания модели

· команд завершения визуализации

Параметры вывода через визуальный компонент задают методы и способы вывода через компонент.

Gl.glViewport(0, 0, AnT.Width, AnT.Height);

Gl.glMatrixMode(Gl.GL_PROJECTION);

Gl.glLoadIdentity();

Glu.gluPerspective(45, (float)AnT.Width / (float)AnT.Height, 0.1, 200);

Gl.glMatrixMode(Gl.GL_MODELVIEW);

Gl.glLoadIdentity();

Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Листинг 5. Настройка параметров вывода и перспективы

Команда glViewport выполняет инициализацию области вывода, параметры, заданные данной команде в листинге 5 показывают что вывод будет производиться на весь объект. Функция glMatrixMode предназначена для того, чтобы задавать матричный режим: будет определена матрица, над которой в дальнейшем будут производиться операции. В данном случае это GL_PROJECTION - матрица проекций. Следующим действием очищается матрица, с помощью функции glLoadIdentity (функция заменяет текущую матрицу на единичную). Далее в листинге устанавливается тип текущей проекции с помощью функции gluPerspective. Функция gluPerspective определена в библиотеке GLU - OpenGL Utility Library (GLU). Эта библиотека является надстройкой над библиотекой OpenGL, реализующей ряд более продвинутых функций. Она так же является свободно-распространяемой и поставляется вместе с библиотекой OpenGL. Данная функция строит пирамиду охвата видимости, основываясь на угле визуального охвата, отношении сторон порта просмотра и установке ближней и дальней плоскости просмотра.

Рисунок 1. Схема обработки перспективы OpenGL

После определения проекции устанавливается объектно-видовая матрица GL_MODELVIEW и также очищается функцией glLoadIdentity. Когда вызывается функция вывода, первым делом производиться очистка окна (т.к. до этого уже мог быть реализован вывод предыдущего кадра - очистка экрана перед визуализацией кадра - это стандартный метод). Для этого используется функция glClear. В качестве параметра, функция получает значения каких буферов ей необходимо очистить - в листинге 5 это буфер цвета и буфер глубины.

4.5 Описание геометрической модели

Модель трехстепенного механического роторного гироскопа Фуко состоит из:

· вращающегося ротора на оси

· неподвижной рамы относительно ротора

· двух подвижных рам относительно ротора в разных направлениях

Для наглядности в интерактивной модели добавлены:

· два балансира на ротор

· утяжелитель на внешнюю раму

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

4.6 Описание модели средствами OpenGL

В данной модели одни объекты зависят от других. Таким первым описать необходимо описать те объекты, которые не зависят от других объектов. Такими объектами являются внутренняя рама и ротор.

Glut.glutSolidTorus(1,12,64,64);

Листинг 6. Внутренняя рама

Функция glutSolidTorus из библиотеки GLUT осуществляет рисование тора (кольцо с круговым сечением). Здесь первый параметр - радиус сечения тора, второй - радиус самого тора, третий и четвертый параметр - количество разбиений по отдельному радиальному сектору и тору соответственно. Разбиения - точность отрисовки негладких кривых на экране, так как пикселями не возможно изобразить идеально гладкую кривую.

Чтобы модель отражала свет, а не поглощала, а также вела себя реалистичнее со светом необходимо придать ей свойства материала. Это означает что ей необходимо задать параметры отражения и рассеивания света.

float[] color = new float[4]{ 0.8f, 0.7f, 0f, 1};

float[] shininess = new float[1]{ 30 };

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, color);

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, color);

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, shininess);

Листинг 7. Свойства материалов

Здесь режим GL_FRONT функции glMaterial означает что свойства материалов будут применены к передней грани. Режим GL_DIFFUSE означает рассеянный свет, режим GL_SPECULAR отраженный свет, а GL_SHININESS его степень. Третьим параметром выступают массивы значений. В данном примере ротор имеет золотое отражение.

Gl.glRotatef(90,1,0,0);

Gl.glRotatef(rt,.0f,.0f,1.0f);

Gl.glTranslated(0,0,-12);

Glut.glutSolidCylinder(0.8d,24d, 64, 64);

Gl.glTranslated(0,0,11.5);

Glut.glutSolidCylinder(10d,1d, 64, 64);

Gl.glTranslated(9,0d,-1);

Glut.glutSolidCylinder(1d,1d, 64, 64);

Gl.glTranslated(-18,0,0); //перенос

Glut.glutSolidCylinder(1d,1d, 64, 64);

Gl.glTranslated(9,0,1.5);

Gl.glRotatef(-rt,.0f,.0f,1.0f);

Листинг 8. Ротор и его вращение

Осью ротора является цилиндр. Функция glutSolidCylinder позволяет его изобразить. Функция имеет четыре параметра: радиус, длина, количество разбиений вдоль и вокруг оси цилиндра. Так как из-за особенностей библиотеки Glut цилиндр по умолчанию расположен в пространстве не вертикально, а горизонтально, одним из оснований в начале координат, и осью на оси Z, его необходимо переместить и повернуть. Осуществляются эти действия функциями glRotate и glTranslate. Функция glTranslate принимает 3 аргумента и перемещает начало координат в точку с координатами x, y, z соответственно параметрам. Функция glRotate принимает 4 параметра, в которых указывается на какой угол, и относительно каких осей будет произведен поворот. В листинге 8 были выполнены поворот по оси x на 90 градусов и перенос по оси z на 12.

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

Так как ротор является вращающейся частью все построения ведутся относительно центра ротора (центра его оси и центра диска). Следовательно, после каких либо переносов, необходимо возвращаться в вышеуказанную позицию.

Для равномерного вращения необходимо разместить функцию поворота перед началом описания вращающегося объекта, задав в качестве угла поворота переменную, и линейно ее увеличивать на определенную величину, от которой будет зависеть скорость вращения объекта. Удобнее всего к данной переменной добавлять величину при каждой отрисовке сцены.

Но так как после описания элемента вращения могут описываться другие элементы, не вращающиеся вместе с вышеописанным объектом, необходимо после описания объекта разместить аналогичную функцию поворота с переменной, противоположной переменной вращения. Так как общая сумма вращения будет равна 0, объекты, описанные ниже останутся неподвижны.

Описание внешней рамы от средней принципиально отличается только наличием утяжелителя.

Gl.glRotatef(-180,0,1,0);

Gl.glTranslated(0,0,-17);

Glut.glutSolidCylinder(0.5d,2d, 64, 64);

Gl.glTranslated(0,0,17);

Gl.glRotatef(180,0,1,0);

Gl.glTranslated(0,0,-17);

Glut.glutSolidCylinder(0.5d,2d, 64, 64);

Gl.glTranslated(0,0,17);

Gl.glRotatef(90,0,1,0);

Glut.glutSolidTorus(1,18,64,64);

Gl.glTranslated(0,-19,0);

Gl.glRotatef(-90,1,0,0);

Glut.glutSolidCylinder(6d,3d,64,64);

Gl.glRotatef(90,0,0,0);

Gl.glTranslated(0,19,0);

Gl.glRotatef(-90,0,1,0);

Листинг 9. Описание внешней рамы

Особого внимания при описании требует положение рамы и осей ее закрепления. Для обеспечения целостности модели и отсутствия артефактов, как и в случае с ротором, оси должны входить в два соседние объекта. Рама должна быть расположена перпендикулярно предыдущей, оси закрепления также должны быть перпендикулярны осям предыдущей рамы.

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

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

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

Gl.glTranslated(0,0,camdis);

Gl.glRotatef(ryt,1.0f,.0f,.0f);

Gl.glRotatef(rxt,0.0f,1.0f,.0f)

Листинг 10. Функции управления камерой

Выполнив необходимые описания, необходимо обозначить окончание отрисовки функцией glFlush вызвать перерисовку компонента вывода методом Invalidate().

4.7 Реализация управления моделью

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

Однако, и здесь не обойтись без трудностей. Описанная модель имеет как минимум два полюса управления (камера и оси), модели не двухмерные, а трехмерные. Следовательно, для реализации управления необходим алгоритм, в соответствии с которым будет осуществляться управление.

Управление необходимо разделить на две основные части, это:

· управление камерой

· управление рамами гироскопа

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

Управление поворотом рам гироскопа, а также и камерой, удобно осуществлять при нажатой клавиши мыши и последующим перемещением мыши. Алгоритм, дающий такую возможность, реализуется так: запоминается положение курсора во время нажатия клавиши, с минимальной задержкой происходят итерации цикла отслеживания координат (в начале каждой итерации курсор смещается в запомненное положение), при смещении мыши в каком либо направлении передаются значения в функцию-обработчик, которая даст результаты для функций, осуществляющих управление моделью, курсор при этом скрывается; при отпускании клавиши цикл прекращает свою работу и курсор появляется вновь.

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

class coord{private int xpos, ypos, xpos_n, ypos_n; float mdx,mdy;

public void set_coord(int xx,int yy){xpos=xx;ypos=yy;}

public void set_coordn(int xn,int yn){xpos_n=xn;ypos_n=yn;}

public float mx(){mdx=0.01f*(xpos_n-xpos);return mdx;}

public float my(){mdy=0.01f*(ypos_n-ypos);return mdy;}

public coord(){mdx=0;mdy=0;}

}

Листинг 11. Класс расчета углов поворота

В листинге 11 приведен такой класс. В данном классе из считанных координат во время смещения вычитаются исходные координаты, соответственное если число положительное узел поворачивается в одну сторону, если же отрицательное то в противоположную. Также получившееся выражение необходимо умножить на коэффициент, зависящий от того, как быстро у вас происходят итерации считывания мыши. В итоге мы получаем значения углов, на которое необходимо повернуть какой либо узел.

Действия, происходящие при обработке нажатия клавиши мыши можно увидеть в листинге 12.

void AnTMouseDown(object sender, MouseEventArgs e)

{x=Cursor.Position.X;

y=Cursor.Position.Y;

if (e.Button == MouseButtons.Left) { Cursor.Hide();}

if (e.Button == MouseButtons.Left){

if(raxis==false){cord.set_coord(Cursor.Position.X,Cursor.Position.Y);click=true;}

if(raxis==true) {cord_n.set_coord(Cursor.Position.X,Cursor.Position.Y);click=true; }}

if (e.Button==MouseButtons.Right) {ConMenu.Show(Cursor.Position.X, Cursor.Position.Y);}

Листинг 12. Обработка нажатия мыши

При нажатии на мышь определяется какая кнопка была нажата. Если это левая кнопка, то скрывается курсор, задаются начальные координаты, и переменной присваивается значение «истина», означающее удержание кнопки. Также в кнопке определяется каким объектом ведется управление, и соответственно значения начальных координат сообщаются в разных случаях разным экземплярам класса. Нажатием правой кнопку вызовется контекстное меню с опциями управления, которое будет описано позже.

Нажав левую кнопку и задав начальные координаты необходимо обработать перемещение.

void AnTMouseMove(object sender, MouseEventArgs e)

{

if(click==true) {if (raxis == false){cord.set_coordn(Cursor.Position.X,Cursor.Position.Y);

ryt+=cord.my()*sens;

rxt+=cord.mx()*sens;

ryn+=cord_n.my()*sens;

rxn+=cord_n.mx()*sens; }

if (raxis == true) {cord_n.set_coordn(Cursor.Position.X,Cursor.Position.Y);

ryt+=cord.my()*sens;

rxt+=cord.mx()*sens;

ryn+=cord_n.my()*sens;

rxn+=cord_n.mx()*sens;

} }

Листинг 13. Обработчик движения мыши

В первую очередь проверяется условие, нажата ли левая кнопка мыши. Далее проверяется, каким объектом производится управление. После этого считываются координаты и передаются как новые в класс расчета углов. Полученные значения из класса прибавляются к переменным, отвечающим за поворот узлов. Также значения углов умножаются на параметр чувствительности, влияющий на скорость смещения узлов модели в зависимости от перемещения мыши.

При отпускании клавиши происходит смена значения переменной на «ложь», означающей отпускание кнопки, и возврат курсора к отображению (листинг 14).

void AnTMouseUp(object sender, MouseEventArgs e)

{click=false;

if (e.Button == MouseButtons.Left) {Cursor.Show();}}

Листинг 14. Обработчик отпускание клавиши

В то время, когда клавиша мыши нажата, необходимо перемещать на каждой итерации указатель мыши. Это условие необходимо добавить в обработчик таймера (листинг 15).

void Timer1Tick(object sender, EventArgs e)

{

Draw();

if(click==true) {Cursor.Position = new Point(x,y);}

}

Листинг 15. Обработчик таймера

В обработчик таймера также добавлена функция визуализации (функция Draw() в листинге 15). Также необходимо задать начальные параметры удаленности камеры, чувствительности мыши, углов поворота, выбранного объекта управления.

bool click=false;

float ryt=0,rxt=0,rxn=0,ryn=-90;

float sens=3f;

float camdis=-80;

bool raxis=false;

float rt=0;

Листинг 16. Задание начальных значений параметров управления

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

Рисунок 2. Редактирование пунктов контекстного меню

Далее необходимо каждому пункту присвоить значения по умолчанию (отмечен или нет).

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

void AxisToolStripMenuItemClick(object sender, EventArgs e)

{

raxis = true;

cameraToolStripMenuItem.Checked = false;

axisToolStripMenuItem.Checked = true;

}

Листинг 17. Переключение режима управления объектом на выбранный

В листинге 17 происходит изменение значения переменной управления, отмечается текущий пункт контекстного меню, предыдущий пункт становится не отмеченным.

В пункте меню выход размещается процедура выхода из приложения.

Выводы

В результате выполнения курсовой работы было разработан программный проект, реализующий интерактивную трехмерную модель идеализированного трехстепенного механического роторного гироскопа Фуко.

Модель обладает интуитивно понятным интерфейсом и интерактивным управлением. При разработке студент совершенствовал свои навыки геометрического моделирования, усвоил основные методы и функции библиотек OpenGL, развил навыки программирования в среде программирования C#.

Программный проект способен демонстрировать работу гироскопа и наглядно позволяет воспринимать принцип действия описанного устройства.

Задача по разработке интерактивной геометрической модели трехстепенного механического роторного гироскопа Фуко, функционирующего идеализированно, можно считать достигнутой.

Колоссальную роль в разработке данного проекта сыграли выбранные средства разработки. Библиотека OpenGL является достаточно гибким и мощным средством программирования компьютерной графики. Язык программирования C#, разработанный для платформы DotNet, также является мощным средством разработки приложений для платформы Windows.

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

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

Список использованных источников

1. OpenGL. Официальное руководство программиста Ву Мейсон, Нейдер Джеки, Девис Том, Шрайнер Дейв.

2. Гироскоп - Википедия [Электронный ресурс]. - Режим доступа: http://ru.wikipedia.org/wiki/%D0%93%D0%B8%D1%80%D0%BE%D1%81%D0%BA%D0%BE%D0%BF (дата обращения: 06.12.12).

3. SharpDevelop 3.2 SoftTorrent.ru - скачать программы без регистрации через торрент [Электронный ресурс]. - Режим доступа: http://softtorrent.ru/windows-soft-torrent/637-sharpdevelop-32.html (дата обращения: 06.12.12).

4. GLUT - Википедия [Электронный ресурс]. - Режим доступа: http://ru.wikipedia.org/wiki/GLUT (дата обращения: 06.12.12).

5. Библиотека OpenGL [Электронный ресурс]. - Режим доступа: http://compgraph.tpu.ru/lib_opengl.htm (дата обращения: 06.12.12).

6. Tao Framework - Википедия [Электронный ресурс]. - Режим доступа: http://ru.wikipedia.org/wiki/Tao_Framework (дата обращения: 06.12.12).

7. Первое 3D приложение [Электронный ресурс]. - Режим доступа: http://www.programmingcpp.narod.ru/3d.htm (дата обращения: 06.12.12).

8. Delphi и OpenGL [Электронный ресурс]. - Режим доступа: http://cube.h1.ru/d_gl.html (дата обращения: 06.12.12).

9. Необходимые операции инициализации OpenGL [Электронный ресурс]. - Режим доступа: http://www.esate.ru/page/initsializatsiya-opengl-v-c-sharp-step-2 (дата обращения: 06.12.12).

Приложение A. Листинг программного проекта

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Windows.Forms;

using Tao.FreeGlut;

using Tao.OpenGl;

using Tao.Platform.Windows;

namespace a2

{

public partial class MainForm: Form

{

public MainForm()

{

InitializeComponent();

AnT.InitializeContexts();

}

bool click=false;

float ryt=0,rxt=0,rxn=0,ryn=-90;

float sens=3f;

float camdis=-80;

bool raxis=false;

float rt=0;

void MainFormLoad(object sender, EventArgs e)

{

// инициализация Glut

Glut.glutInit();

Glut.glutInitDisplayMode(Glut.GLUT_RGB | Glut.GLUT_DOUBLE | Glut.GLUT_DEPTH);

// очитка окна

Gl.glClearColor(0, 0, 0, 1);

// настройка параметров OpenGL для визуализации

Gl.glEnable(Gl.GL_DEPTH_TEST);

Gl.glEnable(Gl.GL_LIGHTING);

Gl.glEnable(Gl.GL_LIGHT1);

float[] bluish = { 1f, 1f, 1f, 0.1f };

Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, bluish);

Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, bluish);

Gl.glLightModeli (Gl.GL_LIGHT_MODEL_COLOR_CONTROL, Gl.GL_SEPARATE_SPECULAR_COLOR);

MessageBox.Show("Здравствуйте! Управление обзором осуществляется левой кнопкой мыши. Для дополнительных параметров вызовите контекстное меню правой кнопкой мыши.","Гироскоп Фуко - Начало работы...");

}

class coord{private int xpos, ypos, xpos_n, ypos_n; float mdx,mdy;

public void set_coord(int xx,int yy){xpos=xx;ypos=yy;}

public void set_coordn(int xn,int yn){xpos_n=xn;ypos_n=yn;}

public float mx(){mdx=0.01f*(xpos_n-xpos);return mdx;}

public float my(){mdy=0.01f*(ypos_n-ypos);return mdy;}

public coord(){mdx=0;mdy=0;}

}

coord cord=new coord();

coord cord_n=new coord();

void Timer1Tick(object sender, EventArgs e)

{

Draw();

if(click==true) {Cursor.Position = new Point(x,y);}

}

int x,y;

void Draw()

{

rt+=15.5f;

Gl.glViewport(0, 0, AnT.Width, AnT.Height);

Gl.glMatrixMode(Gl.GL_PROJECTION);

Gl.glLoadIdentity();

Glu.gluPerspective(45, (float)AnT.Width / (float)AnT.Height, 0.1, 200);

Gl.glMatrixMode(Gl.GL_MODELVIEW);

Gl.glLoadIdentity();

Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);

Gl.glTranslated(0,0,camdis); //отдаляем камеру от начала координат

Gl.glRotatef(ryt,1.0f,.0f,.0f); //вращение камеры вокруг оси y

Gl.glRotatef(rxt,0.0f,1.0f,.0f); //вращение камеры вокруг оси y

Glut.glutSolidTorus(1,12,64,64); //неподвижная внутрянняя рама

Gl.glRotatef(90,1,0,0);// поворот ротора для правильной прорисовки

Gl.glRotatef(rt,.0f,.0f,1.0f); //вращение ротора

float[] color = new float[4]{ 0.8f, 0.7f, 0f, 1}; //Золотой цвет

float[] shininess = new float[1]{ 30 };

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, color); //Цвет ротора

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, color); //Отраженный свет

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, shininess); //Степень отраженного света

Gl.glTranslated(0,0,-12);//перенос

Glut.glutSolidCylinder(0.8d,24d, 64, 64);//ось ротора

Gl.glTranslated(0,0,11.5); //перенос

Glut.glutSolidCylinder(10d,1d, 64, 64); //диск ротора

float[] color2 = new float[4]{.2f,.2f,.2f, 1}; //цвет

float[] shininess2 = new float[1]{ 30 };

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_DIFFUSE, color2); //Цвет

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SPECULAR, color2); //Отраженный свет

Gl.glMaterialfv(Gl.GL_FRONT, Gl.GL_SHININESS, shininess2); //Степень отраженного света

Gl.glTranslated(9,0d,-1);//перенос

Glut.glutSolidCylinder(1d,1d, 64, 64); //балансир1

Gl.glTranslated(-18,0,0); //перенос

Glut.glutSolidCylinder(1d,1d, 64, 64);//балансир 2

Gl.glTranslated(9,0,1.5);

Gl.glRotatef(-rt,.0f,.0f,1.0f);

Gl.glRotatef(ryn,1,0,0);//врещение н рамы

Gl.glRotatef(-90,0,1,0);// оси средней рамы

Gl.glTranslated(0,0,-14);

Glut.glutSolidCylinder(0.5d,2d, 64, 64);

Gl.glTranslated(0,0,14);

Gl.glRotatef(180,0,1,0);

Gl.glTranslated(0,0,-14);

Glut.glutSolidCylinder(0.5d,2d, 64, 64);

Gl.glTranslated(0,0,14);

Gl.glRotatef(-90,0,1,0);

Gl.glRotatef(90,1,0,0);// средняя рама

Glut.glutSolidTorus(1,15,64,64);

Gl.glRotatef(-90,1,0,0);

Gl.glRotatef(rxn,0,0,1);

Gl.glRotatef(-180,0,1,0);// оси внешней рамы

Gl.glTranslated(0,0,-17);

Glut.glutSolidCylinder(0.5d,2d, 64, 64);

Gl.glTranslated(0,0,17);

Gl.glRotatef(180,0,1,0);

Gl.glTranslated(0,0,-17);

Glut.glutSolidCylinder(0.5d,2d, 64, 64);

Gl.glTranslated(0,0,17);

Gl.glRotatef(90,0,1,0);// внешняя рама

Glut.glutSolidTorus(1,18,64,64);

Gl.glTranslated(0,-19,0);

Gl.glRotatef(-90,1,0,0);

Glut.glutSolidCylinder(6d,3d,64,64);

Gl.glRotatef(90,0,0,0);

Gl.glTranslated(0,19,0);

Gl.glRotatef(-90,0,1,0);

Gl.glFlush();

AnT.Invalidate();

}

void AnTMouseDown(object sender, MouseEventArgs e)

{ x=Cursor.Position.X;

y=Cursor.Position.Y;

if (e.Button == MouseButtons.Left) { Cursor.Hide();}

if (e.Button == MouseButtons.Left) {

if (raxis == false) {cord.set_coord(Cursor.Position.X,Cursor.Position.Y); click=true;}

if(raxis==true) {cord_n.set_coord(Cursor.Position.X,Cursor.Position.Y);click=true; }}

if (e.Button==MouseButtons.Right) {ConMenu.Show(Cursor.Position.X, Cursor.Position.Y);}

}

void AnTMouseMove(object sender, MouseEventArgs e)

{

if(click==true) {if (raxis == false){cord.set_coordn(Cursor.Position.X,Cursor.Position.Y);

ryt+=cord.my()*sens;

rxt+=cord.mx()*sens;

ryn+=cord_n.my()*sens;

rxn+=cord_n.mx()*sens; }

if (raxis == true){cord_n.set_coordn(Cursor.Position.X,Cursor.Position.Y);

ryt+=cord.my()*sens;

rxt+=cord.mx()*sens;

ryn+=cord_n.my()*sens;

rxn+=cord_n.mx()*sens;

} }

}

void AnTMouseUp(object sender, MouseEventArgs e)

{

click=false;

if (e.Button == MouseButtons.Left) {Cursor.Show();}

}

void ExitToolStripMenuItemClick(object sender, EventArgs e)

{

Application.Exit();

}

void HighToolStripMenuItemClick(object sender, EventArgs e)

{

sens=5;

highToolStripMenuItem.Checked=true;

lowToolStripMenuItem.Checked=false;

mediumToolStripMenuItem.Checked=false;

}

void MediumToolStripMenuItemClick(object sender, EventArgs e)

{

sens=3f;

mediumToolStripMenuItem.Checked=true;

highToolStripMenuItem.Checked=false;

lowToolStripMenuItem.Checked=false;

}

void LowToolStripMenuItemClick(object sender, EventArgs e)

{

sens=1;

lowToolStripMenuItem.Checked=true;

mediumToolStripMenuItem.Checked=false;

highToolStripMenuItem.Checked=false;

}

void CloseToolStripMenuItemClick(object sender, EventArgs e)

{

camdis=-80;

closeToolStripMenuItem.Checked = true;

farToolStripMenuItem.Checked = false;

closeToolStripMenuItem1.Checked = false;

}

void FarToolStripMenuItemClick(object sender, EventArgs e)

{

camdis=-120;

closeToolStripMenuItem.Checked = false;

farToolStripMenuItem.Checked = true;

closeToolStripMenuItem1.Checked = false;

}

void CloseToolStripMenuItem1Click(object sender, EventArgs e)

{

camdis=-50;

closeToolStripMenuItem.Checked = false;

farToolStripMenuItem.Checked = false;

closeToolStripMenuItem1.Checked = true;

}

void CameraToolStripMenuItemClick(object sender, EventArgs e)

{

raxis = false;

cameraToolStripMenuItem.Checked =true;

axisToolStripMenuItem.Checked =false;

}

void AxisToolStripMenuItemClick(object sender, EventArgs e)

{

raxis = true;

cameraToolStripMenuItem.Checked = false;

axisToolStripMenuItem.Checked = true;

}

}

}

Приложение Б. Снимки экрана работы проекта

Снимок 1. Запуск

Снимок 2. Общий вид

Снимок 3. Контекстное меню

Снимок 4. Выбор элемента контекстного меню

Снимок 5. Отображение модели при нестандартных размерах окна с близкой позицией камеры

Размещено на Allbest.ru


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.