Визуализатор алгоритмов с применением трехмерной графики

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    36,33 Кб
  • Опубликовано:
    2017-07-10
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Визуализатор алгоритмов с применением трехмерной графики

Введение

приложение пользователь программирование интерфейс

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

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

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

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

1. Постановка задачи

.1 Общее описание разрабатываемого приложения

приложение пользователь программирование интерфейс

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

Определим минимум требований к визуализатору алгоритмов:

1)визуализация самых распространенных алгоритмов сортировки;

2)комментирование выполняемых действий;

)удобный и несложный пользовательский интерфейс.

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

1.2 Актуальность приложения

Для любого хорошего специалиста по программированию важно знать алгоритмы и уметь ими пользоваться. Алгоритм в программировании - это понятная и точная последовательность действий. Согласно популярной книге Кормена «Алгоритмы: построение и анализ», алгоритм (англ. - algorithm) - это любая корректно определенная вычислительная процедура, на вход (англ. - input) которой подается некоторая величина или набор величин, и результатом выполнения которой является выходная (англ. - output) величина или набор значений [2]. Другими словами, алгоритмы - это определенный маршрут, по которому следует двигаться для перемещения из точки А в точку Б.

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

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

Обучение алгоритмизации происходит и в высших учебных заведениях. Алгоритмизация входит в состав основ программирования.

Целями разрабатываемого визуализатора алгоритмов являются:

1)использование программы в высшем учебном заведении для учащихся по дисциплине алгоритмизация и основы программирования

2)упрощение понимания работы алгоритмов

)повышение наглядности рассматриваемого материала

)повышение интереса студентов к изучению алгоритмов

2. Анализ существующих систем визуализации

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

1)Визуализатор пирамидальной сортировки СПбГУ ИТМО. При визуализации на экране отображаются состояние массива, пирамида и комментарий к выполняемому действию. Ввод исходных данных не предусмотрен. Алгоритм трассируется только в прямом направлении. Скриншот примера работы программы представлен на рисунке 1.1:

Рисунок 1.1. Визуализатор пирамидальной сортировки СПбГУ ИТМО (Казаков М.А.)

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

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

)В системе Jeliot университета в Йоэнсуу приведены только визуализаторы пузырьковой и быстрой сортировок. При выполнении алгоритмов отображается вычисление выражений, подсвечивается текущий оператор. Пользовательский ввод исходных данных возможен. Трассировка алгоритма в обратном направлении не предусмотрена.

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

3. Техническое предложение

.1 Выбор среды разработки и языка программирования

Для разработки нужно выбрать язык программирования, на котором будет написано приложение. Рассмотрим самые распространенные из объектно-ориентированных языков: Java и C++.

С++ сохраняет наибольшую совместимость с С. Java, на первый взгляд, сохраняет подобие С и С++, но в действительности отличается от них: из языка удалено большое число синтаксических средств, объявленных необязательными. В результате программы на Java бывают более громоздки по сравнению с их аналогами на С++. Сборщик мусора Java требует системных ресурсов, что снижает эффективность выполнения программ. С++ позволяет использовать принцип «захват ресурсов путем инициализации» (RAII), при котором ресурсы ассоциированы с объектом и автоматически освобождаются при разрушении объекта (например, std:vector и std:iostream). В Java есть четко определенные стандарты на ввод-вывод, графику, геометрию, диалог, доступ к базам данных и прочим типовым приложениям. С++ в этом отношении более свободен [3]. Исходя из выше перечисленного, выбор был остановлен на языке С++.

Для программирования нужна определенная среда разработки. Сравним наиболее используемые среды: Visual Studio, XCode и IntelliJ IDEA.Visual Studio поддерживает программирование на Basic, C++, C#, позволяет создавать и подключать сторонние дополнения и различные SDK. В основном приложения, разработанные на VS, написаны под операционную систему Windows, но возможности современных версий этой среды позволяют расширить функционал до кроссплатформенного состояния.- интегрированная среда разработки программного обеспечения под macOS и iOS. Пакет Xcode поддерживает языки C, C++, Swift, Java, AppleScript, Python и другие. Основным недостатком является стабильность среды, вынуждающая вносить дополнительные изменения в свои проекты после выхода очередной версии. Кроме того, для программирования на XCode необходимо иметь соответствующее оборудование на macOS.

IntelliJ IDEA позволяет создавать программы на языках Java, JavaScript, Python, Ruby, Groovy и других. Из недостатков данной среды хорошо выделяется производительность. Время выполнения компиляции, перекомпиляции и тестирования значительно велико, по сравнению с выше указанными средами.

Ввиду более обширного количества возможностей Visual Studio и наибольшей свободы в программировании на С++ выбор был сделан именно на нем.

3.2 Выбор 3D-движка

Современные технологии позволяют применять в приложениях трехмерную графику. Для реализации трехмерного визуализатора алгоритмов сортировок требуется движок, работающий с 3D-графикой. Рассмотрим наиболее распространенные из них: Unreal Engine 4, Ogre3D и JMonkey Engine.

Все перечисленные движки имеют полную совместимость с операционными системами Windows, Linux и Mac, поддержку OpenGL и Direct3D, возможность разработки под мобильные платформы. Полностью открытым исходным кодом обладают только Ogre3D и JMonkey. У Unreal Engine код более закрытый. Такая задумка нацелена на принуждение к использованию продуктов этой компании для разработки на данном движке. Также применение приложений, разработанных на Unreal Engine, в коммерческих целях возможно только с перечислением некоторых процентов с выручки за продукт. Для сравнения, программы, написанные на Ogre и JMonkey, разрешается свободно использовать с любой целью. Основное различие JMonkey Engine и Ogre3D в том, что основой первого является язык программирования Java, а второго - С++.

Для выбора 3D-движка был подобран ряд критериев, необходимых для разработки визуализатора алгоритмов. Соответствие движков критериям отображено в таблице 3.1.

Таблица 3.1. Сравнение 3D-движков

Критерий\ДвижкиUnreal Engine 4Ogre3DJMonkey EngineСовместимость с Windows+++Разработка на С++++-Совместимость с Visual Studio++-Открытый исходный код-++Свободное коммерческое использование-++

По итогам сравнения для разработки был выбран движок Ogre3D.

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

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

С объектно-ориентированным подходом к рендерингу геометрии необходимость во взаимодействии с ней напрямую совершенно отпадает.

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

Для манипуляции объектами в библиотеке используются интуитивно понятные методы, в отличие от обычного 3D API, в котором, например, для вращения объекта нужно добиться правильной трансформации матрицы, вместо просто вызова метода с указанием оси вращения и градусов (радиан) [4].

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

4. Разработка приложения

.1 Архитектура приложения

Проектирование архитектуры приложения является сложной задачей. При её решении необходимо учитывать такие требования к программе, как удобство разработки и сопровождение, надежность, быстродействие. Кроме этого важным свойством архитектуры является понятность или простота. Еще итальянский художник, учёный и изобретатель Леонардо да Винчи говорил: «Простота - это то, что труднее всего на свете; это крайний предел опытности и последнее усилие гения».

Работа разрабатываемого приложения состоит из следующих этапов:

1)пользователь задает исходную последовательность чисел и выбирает нужный алгоритм сортировки

2)менеджер алгоритмов считывает выбранный алгоритм и формирует для него список операций, проводимых при выполнении сортировки

)собранный список операций запоминается визуализатором

)когда алгоритм сформирован, пользователь переключает шаги сортировки

)визуализатор анимирует каждый шаг в трехмерной сцене

Блок-схема работы приложения представлена на рисунке 4.1:


Рисунок 4.1. Блок-схема работы приложения

Структурная схема приложения представлена на рисунке 4.2:

Рисунок 4.2. Структурная схема работы визуализатора

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

Отдельным классом оформлен менеджер алгоритмов Algo. Он содержит метод, считывающий идентификатор алгоритма, методы-составители списка операций, методы вставки операции в список.

Пользовательский интерфейс описан в классе GUI. Для разработки использовалась библиотека CEGUI. Выбор интерфейсной библиотеки аргументирован ее полной совместимостью с движком Ogre3D.

Также был создан класс Convert, состоящий из методов, которые конвертируют передаваемые данные в требуемый формат.

Диаграмма классов изображена на рисунке 4.3:

Рисунок 4.3. Диаграмма классов приложения

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

4.2 Настройка сцены и 3D-моделей

Исходный массив чисел будет отображаться в виде кубических объектов (параллелепипедов). Пользователь, вводя последовательность чисел, задает высоту этих объектов. Параллелепипеды на сцене рисуются встроенными в Ogre фигурами Cube.mesh. Далее они заливаются текстурой синего цвета. При построении массива на экране объекты растягиваются в соответствии с заданными значениями элемента.

Сущности нужно отображать на поверхности. Для этого необходимо при построении сцены создать абстрактную плоскость и покрыть ее материалом. По умолчанию поверхность заливается текстурой серого асфальта. Через интерфейс пользователь может выбирать и менять текстуру заливки плоскости. Материалы для поверхности разрабатывались вручную, их настройки устанавливались во встроенном в Ogre скрипте Examples.material.

Помимо плоскости для установки объектов необходимо также создать задний фон. Он будет заливаться встроенными в Ogre текстурами формата SkyBox. Пользователь также имеет возможность выбирать и изменять фон через интерфейс.

4.3 Разработка кода

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

Настройка исходного массива

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

В MainApp реализован ввод исходного массива чисел, который затем передается в динамические массивы list и listCube. Исходную последовательность задает пользователь, затем программа считывает ее из текстового поля. Массив list, состоящий из переменных класса ListMember, содержит значения исходных чисел и номера сущностей (кубов), которые их изображают. Массив listCube из переменных класса CubeMember содержит сущности (Entity), привязанные к узлам сцены (SceneNode) [4] и, в отличие от предыдущего массива, имеет статическое состояние на протяжении всей работы приложения с одной последовательностью. Члены list же в ходе интерпретации могут перетасовываться. Листинг программы, отвечающий за построение исходного массива (отрывок метода listCreate в MainApp), показан ниже:

vector<int> vecList = ToListInt (gui.listEdit->getText());= vecList.size();*x2 = new int[listLength];(int i=0; i<listLength; i++)

{(vecList[i]==0) vecList[i] = 1;[i] = vecList[i];

}.listStart = new int[listLength];= new ListMember[listLength];= new CubeMember[listLength];(x2);(x2);();

Чтобы список операций можно было корректно считывать из текстового поля и передавать в виде вектора, был разработан метод ToListInt в классе Convert. Метод считывает только цифры из строки, иные символы он воспринимает как пробел. В результате ToListInt возвращает вектор типа int, состоящий из исходных чисел. Листинг определения метода ToListInt представлен ниже:

vector<int> vec(0);

bool setNumber = false;

int number = 0;(int i=0; i<str.size(); i++)

{((str[i]>='0') && (str[i]<='9'))

{(setNumber)

{= (number*10) + ToInt (str[i]);

} else {= true;= ToInt (str[i]);

}

} else {(setNumber) vec.push_back(number);= false;

}

}(setNumber) vec.push_back(number);(vec.size()==0) vec.push_back(1); vec;

Построение алгоритмов

Построением списков операций алгоритмов сортировки занимается менеджер алгоритмов, он же класс Algo. Класс содержит метод createOperationList, который считывает идентификатор алгоритма и запускает нужный алгоритм сортировки.

В Algo находятся методы-составители списка операций для каждого отдельного алгоритма. При создании списка операции записываются в vector типа string, где первым значением в строке служит символ-идентификатор проводимой операции, вторым - элемент, с которым проводится операция, третьим - другой элемент, который при необходимости также задействован в операции. Также при создании списка операций в отдельный вектор записываются комментарии к выполняемым действиям. Эти комментарии в дальнейшем будут выводиться в интерфейсе для пользователя, чтобы он имел представление о выполняемом действии. Для удобства программирования были добавлены методы вставки нужных значений в вектора (push для вектора операций и pushLog для вектора с комментариями к выполняемым действиям). Пример листинга метода-составителя операций для пузырьковой сортировки показан ниже:

int j = 0;buf = 0;(int i=0; i<len; i++)

{(int k=(len-1); k>i; k-)

{(«e», k-1, k);(ToRU(L «Сравним числа»),: StringConverter:toString (l[k]), ToRU (L» и»),: StringConverter:toString (l[k-1]));(l[k] < l [k-1])

{(«s», k-1, k);(Ogre: StringConverter:toString (l[k]), ToRU (L» <»),: StringConverter:toString (l[k-1]), (L», поэтому поменяем их местами»));

buf = l[k];[k] = l [k-1];[k-1] = buf; (ToRU(L «Возвратим числа на место»));

} else {(Ogre: StringConverter:toString (l[k]), ToRU (L» >=»),: StringConverter:toString (l[k-1]), (L», поэтому возвращаем их на место»));

}

push («f», k-1, k);

}

}

Для построения нужного алгоритма вызывается метод createSort в основном классе MainApp. Метод просит менеджера алгоритмов Algo собрать список операций для заданного идентификатора алгоритма, запоминает полученный вектор в глобальном векторе operation класса MainApp, пересобирает массив list из элементов ListMember согласно исходной последовательности, расставляет кубические объекты на сцене в начальном порядке.

Настройка анимаций

При визуализации каждого шага нужно выдвигать и перемещать объекты на сцене на нужное место. Во время анимации шага на сцене меняется положение кубиков, а в коде меняется только массив list. Массив listCube, состоящий из самих кубов, остается в начальном состоянии. Главный плюс такого решения в отсутствии необходимости перерисовывать объекты прямо на сцене. Здесь меняется только численный массив в коде, на сцене лишь изменяются координаты объектов. Следовательно, приложение потребляет меньше оперативной памяти на графическую отрисовку.

Визуализация шагов производится с помощью методов nextStepSort и lastStepSort, отвечающих за следующий и предыдущий шаги соответственно. Методы считывают идентификатор операции, проводимой с элементами в данном шаге, из вектора operation и вызывает соответствующую анимацию, передавая в нее номера элементов, которые нужно переместить на сцене. Листинг примера реализации анимации, в которой два элемента меняются местами, показан ниже:

Ogre: Vector3 vec1 = listCube [list[num1].numCube].node->getPosition();: Vector3 vec2 = listCube [list[num2].numCube].node->getPosition();point = vec2.x;(vec1.x < point)

{.x += 1;.x -= 1;[list[num1].numCube].node->setPosition(vec1);[list[num2].numCube].node->setPosition(vec2);

}buff = list[num1];[num1] = list[num2];[num2] = buff;

В приложении требуется реализовать, помимо пользовательского переключения шагов алгоритма, автоматический режим визуализации. При включении автоматического переключения шагов запускается таймер в переопределенном движковом методе frameRenderingQueued, который каждые 50 шагов визуализирует следующий шаг. Листинг реализации таймера представлен ниже:

4.4 Проектирование пользовательского интерфейса

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

Разработка элементов интерфейса

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

кнопку выхода;

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

переключатели для выбора алгоритма сортировки;

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

поле для отображения комментариев к визуализируемому шагу;

кнопки для изменения вида сцены (смены положения камеры, изменение текстуры поверхности / фона, отключение теней).

Для настройки интерфейса при построении сцены в основном классе MainApp вызывается метод createGUI класса GUI. Метод устанавливает ресурсы, необходимые для работы интерфейса, подключает используемую графическую схему (в приложении используется стандартная схема TaharezLook пакета CEGUI), создает элементы интерфейса (виджеты) и настраивает их видимость. Все виджеты располагаются на одном листе mySheet. При создании каждого из них вызывается соответствующий метод в классе GUI. Для корректного отображения русских символов на экране реализован метод ToRU в классе Convert.

Взаимодействие пользователя с элементами

Для выполнения нужных действий при нажатии по виджетам реализованы отдельные методы в основном классе MainApp. Чтобы при тапе по виджету вызывался нужный метод, при построении сцены настраиваются указатели для всех нажимаемых элементов.

Интерфейс должен занимать минимум места на экране, чтобы не создавать пользователю препятствия и неудобства при просмотре. Для выполнения данной цели необходимо компактно расположить необходимые кнопки и скрывать неиспользуемые виджеты. Некоторые элементы имеют статическое положение на экране (кнопки изменения камеры, выхода). Интерфейс для настройки сцены пользователь может вручную разворачивать / сворачивать на экране. При старте приложения для работы с алгоритмами доступен только интерфейс ввода исходной последовательности. После создания исходного массива на сцене, этот интерфейс скрывается, и на его месте отображаются кнопки для выбора алгоритма, переключения шагов, работы с автоматическим режимом, поле для комментариев, кнопка возврата ко вводу последовательности (при тапе по ней разворачивается интерфейс для ввода и сворачивается интерфейс работы с алгоритмом). Указатели на кнопки сворачивания / разворачивания отдельных групп виджетов также определяются при создании сцены.

Измерение скорости работы алгоритмов

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

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

Расчет времени производится для эталонного компьютера с частотой 1 ГГц. При расчете времени сортировки учитывается количество операций, проводимых в алгоритме. Считаем, что одна операция равна одному машинному такту. Длительность одного машинного такта обратно пропорциональна тактовой частоте процессора. Следовательно, для выбранного эталонного компьютера время машинного такта составит 1/1 ГГц, что в переводе в секунды равно 1 нс. Листинг реализации расчета скорости работы алгоритмов представлен ниже:

CEGUI: String report = ToRU (L «Скорость работы алгоритмов: \n»);

vector<string> operList;(int i=0; i<algo.algoSum; i++)

{.logOn = false;.createOperationList (listLength, i+1);= algo.vec;+= algo.algoName[i];+= «-»;+= ToString (operList.size());+= ToRU (L» нс \n»);.clear();

}

5. Тестирование

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

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

В текстовое поле для ввода исходной последовательности можно вводить любые символы. Для перевода строки из текстового поля в массив из чисел используется метод ToListInt в классе Convert. Он считывает только цифры, что предохраняет код от попытки использования других символов. Любой символ, не являющийся цифрой, метод считает за пробел. Также, на случай наличия нескольких таких пробелов между числами, в методе имеется флаг setNumber. При значении этой переменной ИСТИНА посимвольно собирается число. При значении ЛОЖЬ полученное число записывается в массив, если оно не было записано до этого, далее происходит ожидание на появление следующего числа в строке. На случай ввода строки без чисел, метод возвращает список с одним элементом равным 1. Если один из элементов списка равен 0, то метод приравнивает его к 1. Такое условие необходимо для корректного отображения кубического объекта, привязанного к элементу, на экране, так как сущность с нулевой высотой будет не видна на сцене.

При вводе больших данных, порядка 500 элементов, списки операций для каждого алгоритма начинают собираться чуть медленнее. На создание алгоритма для таких массивов уходит порядка 1-1,5 секунд. Расчет скорости работы алгоритмов занимает количество времени, примерно большее во столько раз, сколько алгоритмов реализовано в программе. Учитывая, что тестирование проводилось на относительно среднем компьютере, такая скорость работы с большим количеством данных является приемлемой.

Во время переключения шагов скрываются кнопки, которые нельзя нажимать данный момент. Например, при запуске автоматического режима активны только кнопки «Pause» и «Stop», после создания отчета о скорости работы алгоритмов скрывается кнопка «Создать» до тех пор, пока не будет введена другая исходная последовательность. Такой метод необходим, чтобы пользователь не мог сломать работу приложения во время визуализации алгоритма.

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

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

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

6. Разработка руководства пользователя

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

В руководство пользователя для разрабатываемого визуализатора были добавлены следующие разделы:

- введение;

- запуск и настройка приложения;

работа с исходными данными;

работа с алгоритмами (Выбор и визуализация алгоритма, измерение скорости);

работа с графикой (Настройка камеры, изменение текстур и теней);

об авторах.

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

Заключение

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

Разработанный визуализатор имеет следующие возможности:

- визуализация самых распространенных алгоритмов сортировки (выбором, вставками, пузырьковая, быстрая, сортировка Шелла);

комментирование выполняемых действий;

удобный и компактный пользовательский интерфейс;

пошаговый и автоматический режим выполнения сортировки;

трассировка алгоритма в прямом и обратном направлении;

автоматический (случайный) и пользовательский ввод данных;

измерение скорости работы алгоритмов;

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

удобство сопровождения и модификации приложения.

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

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

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

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

Результаты работы над данной выпускной квалификационной работой были представлены на конференциях: Х Ежегодная научная сессия аспирантов и молодых ученых, Молодые исследователи регионам, Вузовская наука - региону. Тезисы докладов опубликованы в сборниках работ.


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

1.Визуализатор алгоритмов с применением трехмерной графики. Костров А.В. В сборнике: Материалы межрегиональной научной конференции Х ежегодной научной сессии аспирантов и молодых ученых. Том 1. 2017. С. 81-85.

2.Кормен Т. Алгоритмы: построение и анализ / Кормен Т., Лейзерсон Ч., Ривест Р. - М.: МЦНМО, 2001. - 960 с.

.Страуструп Б. Язык программирования С++ / Страуструп Б. - М.: Бином, 2011. - 1136 с.

4.Ogre3D Графический 3D-движок с открытым исходным кодом [Электронный ресурс]: офиц. сайт. - Режим доступа: #"justify">Приложение 1

Руководство пользователя

Введение

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

Возможности программы:

·автоматический / ручной ввод данных;

·автоматический / ручной режимы переключения шагов алгоритма

·визуализация распространенных алгоритмов сортировки (выбором, вставками, пузырьковая, быстрая, Шелла)

·комментирование выполняемых действий

·сравнение алгоритмов по скорости работы

·трехмерная графика

·возможность изменения графики на сцене

·смена камеры

Цикл работы программы:

.Задается исходная последовательность чисел.

.Выбирается алгоритм сортировки.

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

.Переключаются шаги алгоритма, в это время на сцене шаг визуализируется.

Системные требования:

·Windows XP и выше

·Частота процессора 1 ГГц

·ОЗУ 256 Мб

·Видеокарта с поддержкой 3D

·DirectX 11

1.Запуск и настройка приложения

Запустите exe-файл «AlgoVisual3D» из директории приложения.


В окне настроек выберите «Direct3D9 Rendering Subsystem». При выборе иных систем рендеринга корректность работы приложения не гарантируется.

Для отображения в оконном режиме установите в «Full Screen» значение No. Для полноэкранного режима - Yes.

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

Выберите требуемое разрешение экрана в «Video Mode».

Запустите приложение по кнопке «ОК».

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

Выйти из программы можно по кнопке «Выйти» в левом верхнем углу окна.

2.Работа с исходными данными

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

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

Замечание! Программа считывает только натуральные значения. При вводе нуля он приравнивается к 1. При отсутствии цифр в поле для ввода исходная последовательность приравнивается к списку из одного элемента, равного 1.

Также можно воспользоваться генерацией случайных списков по кнопке «Auto». Генерация случайных чисел производится в диапазоне от 1 до 15 с длиной массива от 3 до 10.

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

Вернуться ко вводу исходных данных можно по кнопке «Поменять числа». При этом кубические объекты, находящиеся на сцене, уничтожатся.

3.Работа с алгоритмами

3.1.Выбор и визуализация алгоритма

После построения списка появляется интерфейс работы с алгоритмами.



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

Ручное переключение шагов алгоритма вперед / назад осуществляется кнопками «next» / «last». Для включения автоматического режима необходимо нажать «play». Чтобы приостановить автоматическую визуализацию алгоритма нужно нажать кнопку «pause». Кнопка «stop» сбрасывает алгоритм к начальному состоянию.

Во время выбора и визуализации алгоритма выполняемое действие комментируется в поле раздела «Комментарии:».

Вернуться ко вводу исходного массива можно по кнопке «Поменять числа». При этом все кубические объекты на сцене уничтожатся.

3.2.Измерение скорости

Измерение скорости возможно только после ввода исходного массива и построения его в виде кубических объектов на сцене.

Для раскрытия интерфейса измерения скорости необходимо тапнуть по кнопке «Скорость». Скрыть интерфейс можно аналогичным образом.



В текстовом поле интерфейса для измерения скорости отображается исходная последовательность чисел.

В поле под разделом «Отчет:» записывается отчет о замерах скорости работы алгоритмов. Для создания отчета необходимо нажать кнопку «Создать».

Расчет скорости алгоритмов производится в наносекундах. В расчете учитывается количество выполняемых действий в алгоритме. Считается, что одна выполняемая операция равна одному машинному такту. Период машинного такта рассчитывается по формуле T = 1 / v, где T - период машинного такта, v - частота процессора. Если считать, что компьютер имеет частоту процессора 1 ГГц, то время его одного машинного такта составит 1 нс. В приложении период рассчитывается для эталонного компьютера с частотой 1 ГГц.

4.Работа с графикой

4.1 Настройка камеры

Положение камеры задается кнопками «1-4» в правом верхнем углу экрана. Кнопки доступны в течение всей работы программы. В приложении доступно для изменения 4 положения камеры.

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

Также положение и направление камеры можно изменять вручную клавишами на клавиатуре:

A / D - влево / вправо по x;

Q / E - вниз / вверх по y;

W / S - вперед / назад по z;

J / L - наклон влево / вправо по x;

U / O - наклон вниз / вверх по y;

I / K - наклон вперед / назад по z.

Оси координат на сцене располагаются следующим образом:


4.2 Изменение текстур и теней

Для раскрытия интерфейса изменения графики необходимо нажать по кнопке «Графика». Скрытие интерфейса производится аналогичным образом. Изменение графики доступно в течение всей работы программы.


При переключении фона меняется текстура неба. Выбор производится кнопками «1-3» в соответствующем разделе. При переключении поверхности меняется текстура плоскости, на которой находятся кубические объекты. Выбор также производится кнопками «1-3» в соответствующем разделе. В приложении доступно для выбора 3 текстуры фона неба и 3 текстуры заливки поверхности.

В приложении доступно изменение отображения тени от кубических объектов на сцене. Включение/отключение тени производится кнопками «Тень ON» / «Тень OFF».

Об авторах

Разработчик: Костров Антон Витальевич.

Научный руководитель: Кочкин Дмитрий Валерьевич.

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

За основу взят игровой движок Ogre3D, версия 1.9. Некоторые текстуры частично изменены. Источник www.ogre3d.org.

Интерфейс: CEGUI, версия 0.7.9. Текстуры оригинал. Источник cegui.org.uk.

Коммерческая реализация приложения запрещена.

Приложение 2

Листинг программы

Листинг файла ListMember.h

class ListMember

{:value; // значение числаnumCube; // номер сущности

};

Листинг файла CubeMember.h

#include <OgreEntity.h>

#include <OgreSceneManager.h>

CubeMember

{:();~CubeMember();: Entity*entity; // сущность: SceneNode*node; // узел сцены

};

Листинг файла Convert.h

#include <iostream>

#include <CEGUI.h>

namespace std;

namespace Convert

{ToInt (char x);

int Pow (int x, int y); // возведение в степень

vector<int> ToListInt (CEGUI: String str);: String ToString (vector<int> x);: String ToRU (wchar_t strw[]); // convert to ru lang

}

Листинг файла Convert.cpp

#include «Convert.h»

Convert: ToInt (char x)

{(x)

{'1':return 1;'2':return 2;'3':return 3;'4':return 4;'5':return 5;'6':return 6;'7':return 7;'8':return 8;'9':return 9;'0':return 0;:break;

}0;

}Convert: Pow (int x, int y)

{z = 1;(int i=0; i<y; i++) z = z*x;z;

}

: String Convert: ToString (vector<int> x)

{: String str = «»; // create empty string(int i=0; i<x.size(); i++)

{+= ToString (x[i]);+= «»;

}str;

}

<int> Convert: ToListInt (CEGUI: String str)

{<int> vec(0);setNumber = false; // истина - собираем число, ложь - некорректные символыnumber = 0; // собираемое число(int i=0; i<str.size(); i++)

{((str[i]>='0') && (str[i]<='9'))

{(setNumber)

{= (number*10) + ToInt (str[i]); // дополнили число

} else {= true; // число= ToInt (str[i]); // начали собирать число

}

} else {(setNumber) vec.push_back(number); // записали собранное число

setNumber = false; // некорректные символы или пробелы

}

}(setNumber) vec.push_back(number);

// записали собранное число, если последний символ - цифра

if (vec.size()==0) vec.push_back(1); // если чисел в списке нет

return vec;

}

: String Convert: ToRU (wchar_t strw[])

{: String str;(int i=0; i<wcslen(strw); i++) str += strw[i];str;

}

Листинг файла GUI.h

#include <iostream>

#include «Convert.h»

#include <CEGUI.h>

#include <RendererModules/Ogre/CEGUIOgreRenderer.h> //from 0.8 it's just Ogre/Renderer.h

using namespace std;namespace Convert;

Mygui

{:(void);~Mygui(void);CEGUI: Window* createGUI(void); // Постойка интерфейсаvoid createResourses(void); // группы ресурсовvoid createWidgets(void); // widgetsvoid quitButton(void); // кнопка выходаvoid camStaticText(void); // text cameravoid camButton1 (void); // кнопка camera 1void camButton2 (void); // кнопка camera 2void camButton3 (void); // кнопка camera 3void camButton4 (void); // кнопка camera 4void listStaticText(void); // text для ввода исх. последовательностиvoid listEditBox(void); // поле для ввода исх. последовательностиvoid listAutoButton(void); // кнопка для создания рандом list

virtual void listOkButton(void); // кнопка для создания исх. последовательности

virtual void algoOffButton(void); // close algovoid algoStaticText(void); // text для algovoid algoNameText(void); // name algovoid algoLButton(void); // algo leftvoid algoRButton(void); // algo rightvoid stepStaticText(void); // text для stepsvoid stepStopButton(void); // кнопка для stop allvoid stepPlayButton(void); // кнопка для play auto modevoid stepPauseButton(void); // кнопка для pause auto modevoid stepLastButton(void); // кнопка для last manual modevoid stepNextButton(void); // кнопка для next manual modevoid logStaticText(void); // textvoid logList(void); // логированиеvoid speedButtonOn(void); // кнопка speed onvoid speedButtonOff(void); // кнопка speed offvoid speedListTextStaticText(void);void speedListStaticText(void);void speedReportStaticText(void); // text для report in speedvoid speedReportOkButton(void); // create report in speedvoid speedReportEditBox(void); // editbox для report in speedvoid sceneButtonOn(void); // кнопка scene onvoid sceneButtonOff(void); // кнопка scene offvoid skyStaticText(void); // text skyvoid skyButton1 (void); // кнопка sky 1void skyButton2 (void); // кнопка sky 2void skyButton3 (void); // кнопка sky 3void groundStaticText(void); // text groundvoid groundButton1 (void); // кнопка ground 1void groundButton2 (void); // кнопка ground 2void groundButton3 (void); // кнопка ground 3void shadowButtonOn(void); // кнопка shadow onvoid shadowButtonOff(void); // кнопка shadow offvoid listShow(void); // visible = true - невидимостьvoid listHide(void); // visible = falsevoid algoShow(void); // visible = truevoid algoHide(void); // visible = falsevoid sceneShow(void); // scene развернутьvoid sceneHide(void); // scene свернутьvoid speedShow(void); // speed развернутьvoid speedHide(void); // speed свернутьvoid stepEnableBegin(void); // enable когда список собралсяvoid stepEnableEnd(void); // enable когда список закончилсяvoid stepEnablePlay(void); // enable когда нажали плейvoid stepEnablePause(void); // enable когда нажали pausevoid stepDisable(void); // enable = false

: Window*mySheet; // лист для виджетов: Window*quit; // quit Button: Window*camText; // camera text: Window*cam1; // camera Button: Window*cam2; // camera Button: Window*cam3; // camera Button: Window*cam4; // camera Button

CEGUI: Window*listSText; // text для ввода исх. последовательности: Window*listEdit; // поле для ввода исх. последовательности: Window*listAuto; // кнопка для создания рандом list: Window*listOk; // кнопка для создания исх. последовательности

CEGUI: Window*algoOff; // close algo: Window*algoSText; // text для algo: Window*algoText; // name algo: Window*algoL; // algo left: Window*algoR; // algo right: Window*stepSText; // text для steps: Window*stepStop; // stop button: Window*stepPlay; // play button: Window*stepPause; // pause button: Window*stepLast; // last button: Window*stepNext; // next button: Window*logSText; // text: Window*logText; // поле для вывода комментариев (логирование) 1

CEGUI: Window*speedOn; // speed Button: Window*speedOff; // speed Button: Window*speedListText; // text для исх. последовательности in speed: Window*speedList; // text исх. последовательности in speed: Window*speedReportText; // text для отчета in speed: Window*speedReportOk; // button для create отчета in speed: Window*speedReportLog; // log отчета in speed: Window*sceneOn; // scene Button: Window*sceneOff; // scene Button: Window*skyText; // sky text: Window*sky1; // sky Button: Window*sky2; // sky Button: Window*sky3; // sky Button: Window*groundText; // groung text: Window*ground1; // ground Button: Window*ground2; // ground Button: Window*ground3; // ground Button: Window*shadowOn; // shadow Button: Window*shadowOff; // shadow Button

};

Листинг файла GUI.cpp

#include «GUI.h»

CEGUI: Window* Mygui:createGUI(void)

{(); // установим группы ресурсов: WindowManager &wmgr = CEGUI: WindowManager:getSingleton();= wmgr.createWindow («DefaultWindow», «MySheet»);(); // настраиваем виджеты();();();();();mySheet;

}Mygui:createResourses(void)

{: Imageset:setDefaultResourceGroup («Imagesets»);: Font:setDefaultResourceGroup («Fonts»);: Scheme:setDefaultResourceGroup («Schemes»);: WidgetLookManager:setDefaultResourceGroup («LookNFeel»);: WindowManager:setDefaultResourceGroup («Layouts»);

}Mygui:createWidgets(void)

{(); // создали кнопку выхода();(); // кнопки камеры(); // кнопки камеры(); // кнопки камеры(); // кнопки камеры

listStaticText();(); // поле для ввода исх. последовательности

listAutoButton();();();();();();();();();();();();();();(); // логирование (комментирование)();();(); // text для исх. последовательности in speed(); // text исх. последовательности in speed(); // text для report in speed(); // button для create report in speed(); // editbox для report in speed();();();(); // кнопки sky(); // кнопки sky(); // кнопки sky();(); // кнопки ground(); // кнопки ground(); // кнопки ground();();

}Mygui:quitButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «QuitButton»);>setText (ToRU(L «Выход»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.025, 0)));>addChildWindow(quit); // прикрепим кнопку выхода на лист

}Mygui:camStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «CamStaticText»);>setText (ToRU(L «Выберите камеру:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.20, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.80, 0), CEGUI:UDim (0, 0)));>addChildWindow(camText); // прикрепим статиктекст на лист

}Mygui:camButton1 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «CamButton1»);->setText («1»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.8, 0), CEGUI:UDim (0.05, 0)));>addChildWindow(cam1); // прикрепим кнопку на лист

}Mygui:camButton2 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «CamButton2»);->setText («2»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.85, 0), CEGUI:UDim (0.05, 0)));>addChildWindow(cam2); // прикрепим кнопку на лист

}Mygui:camButton3 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «CamButton3»);->setText («3»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.9, 0), CEGUI:UDim (0.05, 0)));>addChildWindow(cam3); // прикрепим кнопку на лист

}Mygui:camButton4 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «CamButton4»);->setText («4»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.95, 0), CEGUI:UDim (0.05, 0)));>addChildWindow(cam4); // прикрепим кнопку на лист

}Mygui:listStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «ListStaticText»);

listSText->setText (ToRU(L «Введите последовательность чисел:»));

listSText->setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.825, 0)));>addChildWindow(listSText); // прикрепим статиктекст на лист

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Editbox», «ListEditBox»);>setText («7 3 1 6 10 9 2 5 8 4»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.875, 0)));>addChildWindow(listEdit); // прикрепим editBox на лист

}Mygui:listAutoButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «ListAutoButton»);>setText («Auto»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.925, 0)));>addChildWindow(listAuto); // прикрепим button на лист

}Mygui:listOkButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «ListOkButton»);>setText (ToRU(L «Создать»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.175, 0), CEGUI:UDim (0.925, 0)));>addChildWindow(listOk); // прикрепим button на лист

}Mygui:algoOffButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «AlgoOffButton»);>setText (ToRU(L»< Поменять числа»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.20, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.525, 0)));>addChildWindow(algoOff); // прикрепим button на лист

}Mygui:algoStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «AlgoStaticText»);>setText (ToRU(L «Введите ID алгоритма:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.575, 0)));>addChildWindow(algoSText); // прикрепим статиктекст на лист

}Mygui:algoNameText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «AlgoNameText»);>setText («123»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.20, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.075, 0), CEGUI:UDim (0.625, 0)));>addChildWindow(algoText); // прикрепим статиктекст на лист

}Mygui:algoLButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «AlgoLButton»);>setText(«<»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.625, 0)));>addChildWindow(algoL); // прикрепим button на лист

}Mygui:algoRButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «AlgoRButton»);>setText(«>»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.275, 0), CEGUI:UDim (0.625, 0)));>addChildWindow(algoR); // прикрепим button на лист

}Mygui:stepStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «StepStaticText»);>setText (ToRU(L «Шаги:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.675, 0)));>addChildWindow(stepSText); // прикрепим статиктекст на лист

}Mygui:stepStopButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «StepStopButton»);>setText («stop»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.725, 0)));>addChildWindow(stepStop); // прикрепим button на лист

}Mygui:stepPlayButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «StepPlayButton»);>setText (ToRU(L «play»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.725, 0)));>addChildWindow(stepPlay); // прикрепим button на лист

}Mygui:stepPauseButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «StepPauseButton»);>setText (ToRU(L «pause»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.2, 0), CEGUI:UDim (0.725, 0)));>addChildWindow(stepPause); // прикрепим button на лист

}Mygui:stepLastButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «StepLastButton»);>setText (ToRU(L «last»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.725, 0)));>addChildWindow(stepLast); // прикрепим button на лист

}Mygui:stepNextButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «StepNextButton»);>setText (ToRU(L «next»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.05, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.275, 0), CEGUI:UDim (0.725, 0)));>addChildWindow(stepNext); // прикрепим button на лист

}Mygui:logStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «LogStaticText»);>setText (ToRU(L «Комментарии:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.775, 0)));>addChildWindow(logSText); // прикрепим статиктекст на лист

}Mygui:logList(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/MultiLineEditbox», «logText1»);

logText->setText (ToRU(L»!!! Введите исходную последовательность чисел. Затем выберите алгоритм!!!»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.15, 0)));

logText->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.025, 0), CEGUI:UDim (0.825, 0)));>addChildWindow(logText); // прикрепим logText1 на лист

}Mygui:speedButtonOn(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SpeedButtonOn»);>setText (ToRU(L «Скорость | ^»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.35, 0), CEGUI:UDim (0.925, 0)));>addChildWindow(speedOn); // прикрепим кнопку на лист

}Mygui:speedButtonOff(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SpeedButtonOff»);>setText (ToRU(L «Скорость | _»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.35, 0), CEGUI:UDim (0.475, 0)));>addChildWindow(speedOff); // прикрепим кнопку на лист

}Mygui:speedListTextStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «SpeedListTextStaticText»);

speedListText->setText (ToRU(L «Исходная последовательность:»));

speedListText->setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.35, 0), CEGUI:UDim (0.525, 0)));>addChildWindow(speedListText); // прикрепим статиктекст на лист

}Mygui:speedListStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «SpeedListStaticText»);>setText («empty»);>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.35, 0), CEGUI:UDim (0.575, 0)));>addChildWindow(speedList); // прикрепим статиктекст на лист

}Mygui:speedReportStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «SpeedReportStaticText»);>setText (ToRU(L «Отчет:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.35, 0), CEGUI:UDim (0.625, 0)));>addChildWindow(speedReportText);

}Mygui:speedReportOkButton(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SpeedReportOkButton»);>setText (ToRU(L «Создать»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.5, 0), CEGUI:UDim (0.625, 0)));>addChildWindow(speedReportOk); // прикрепим кнопку на лист

}Mygui:speedReportEditBox(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/MultiLineEditbox», «SpeedReportEditBox»);

speedReportLog->setText (ToRU(L»!!! Нажмите кнопку Создать для создания отчета о скорости работы алгоритмов!!!»));

speedReportLog->setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.30, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.35, 0), CEGUI:UDim (0.675, 0)));>addChildWindow(speedReportLog); // прикрепим log на лист

}Mygui:sceneButtonOn(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SceneButtonOn»);>setText (ToRU(L «Графика | ^»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.825, 0), CEGUI:UDim (0.925, 0)));>addChildWindow(sceneOn); // прикрепим кнопку на лист

}Mygui:sceneButtonOff(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SceneButtonOff»);>setText (ToRU(L «Графика | _»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.825, 0), CEGUI:UDim (0.65, 0)));>addChildWindow(sceneOff); // прикрепим кнопку на лист

}Mygui:skyStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «SkyStaticText»);>setText (ToRU(L «Выберите фон неба:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.675, 0), CEGUI:UDim (0.7, 0)));>addChildWindow(skyText); // прикрепим статиктекст на лист

}Mygui:skyButton1 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SkyButton1»);->setText («1»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.675, 0), CEGUI:UDim (0.75, 0)));>addChildWindow(sky1); // прикрепим кнопку на лист

}Mygui:skyButton2 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SkyButton2»);->setText («2»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.775, 0), CEGUI:UDim (0.75, 0)));>addChildWindow(sky2); // прикрепим кнопку на лист

}Mygui:skyButton3 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «SkyButton3»);->setText («3»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.875, 0), CEGUI:UDim (0.75, 0)));>addChildWindow(sky3); // прикрепим кнопку на лист

}Mygui:groundStaticText(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/StaticText», «GroundStaticText»);>setText (ToRU(L «Выберите поверхность:»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.30, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.675, 0), CEGUI:UDim (0.8, 0)));>addChildWindow(groundText); // прикрепим статиктекст на лист

}Mygui:groundButton1 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «GroundButton1»);->setText («1»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.675, 0), CEGUI:UDim (0.85, 0)));>addChildWindow(ground1); // прикрепим кнопку на лист

}Mygui:groundButton2 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «GroundButton2»);->setText («2»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.775, 0), CEGUI:UDim (0.85, 0)));>addChildWindow(ground2); // прикрепим кнопку на лист

}Mygui:groundButton3 (void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «GroundButton3»);->setText («3»);->setSize (CEGUI:UVector2 (CEGUI:UDim (0.1, 0), CEGUI:UDim (0.05, 0)));->setPosition (CEGUI:UVector2 (CEGUI:UDim (0.875, 0), CEGUI:UDim (0.85, 0)));>addChildWindow(ground3); // прикрепим кнопку на лист

}Mygui:shadowButtonOn(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «ShadowButtonOn»);>setText (ToRU(L «Тень ON»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.675, 0), CEGUI:UDim (0.925, 0)));>disable();>addChildWindow(shadowOn); // прикрепим кнопку на лист

}Mygui:shadowButtonOff(void)

{= CEGUI: WindowManager:getSingleton().createWindow («TaharezLook/Button», «ShadowButtonOff»);>setText (ToRU(L «Тень OFF»));>setSize (CEGUI:UVector2 (CEGUI:UDim (0.15, 0), CEGUI:UDim (0.05, 0)));>setPosition (CEGUI:UVector2 (CEGUI:UDim (0.825, 0), CEGUI:UDim (0.925, 0)));>addChildWindow(shadowOff); // прикрепим кнопку на лист

}Mygui:listShow(void)

{>show();>show();>show();>show();

}Mygui:listHide(void)

{>hide();>hide();>hide();>hide();

}Mygui:algoShow(void)

{>show();>show();>show();>show();>show();>show();>show();>show();>show();>show();>show();>show();>show();>show();

}Mygui:algoHide(void)

{>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();>hide();

}Mygui:sceneShow(void)

{>hide();>show();>show();->show();->show();->show();>show();->show();->show();->show();>show();>show();

}Mygui:sceneHide(void)

{>show();>hide();>hide();->hide();->hide();->hide();>hide();->hide();->hide();->hide();>hide();>hide();

}Mygui:speedShow(void)

{>hide();>show();>show();>show();>show();>show();>show();

}Mygui:speedHide(void)

{>show();>hide();>hide();>hide();>hide();>hide();>hide();

}Mygui:stepEnableBegin(void)

{>disable();>enable();>disable();>disable();>enable();

}Mygui:stepEnableEnd(void)

{>enable();>disable();>disable();>enable();>disable();

}Mygui:stepEnablePlay(void)

{>enable();>disable();>enable();>disable();>disable();

}Mygui:stepEnablePause(void)

{>enable();>enable();>disable();>enable();>enable();

}Mygui:stepDisable(void)

{>disable();>disable();>disable();>disable();>disable();

}

Листинг файла Algo.h

#include <iostream>

#include <OgreRoot.h>

#include <vector>

#include «Convert.h»

namespace std;namespace Convert;

Algo

{:();~Algo();void createOperationList (int length, int sort); // выбор алгоритмаvoid createSelection (int l[], int len); // Selection Sortvoid createBubble (int l[], int len); // Bubble Sortvoid createInsert (int l[], int len); // Insert Sortvoid createQuick (int l[], int len); // quick Sortvector<int>quickSort (vector<int> data, int const len, int p);void createShell (int l[], int len); // shell Sortvoid push (string oper, int num);void push (string oper, int num1, int num2);void pushLog (CEGUI: String l1);void pushLog (CEGUI: String l1, CEGUI: String l2);void pushLog (CEGUI: String l1, CEGUI: String l2, CEGUI: String l3);void pushLog (CEGUI: String l1, CEGUI: String l2, CEGUI: String l3, CEGUI: String l4);void pushLog (CEGUI: String l1, CEGUI: String l2, CEGUI: String l3, CEGUI: String l4, CEGUI: String l5);

algoSum; // количество алгоритмов<CEGUI: String>algoName; // названия алгоритмов

intstepSum; // количество шагов*listStart; // начальный результат (список)*listResult; // конечный результат (список)<std:string>vec; // список операций алгоритма<CEGUI: String>logSort; // комментарийlogOn; // записывать ли комментарии

};

Листинг файла Algo.cpp

#include «Algo.h»

Algo: Algo()

{

algoSum = 5; // количество алгоритмов

algoName.push_back (ToRU(L «Выбором»));

algoName.push_back (ToRU(L «Пузырьковая»));.push_back (ToRU(L «Вставками»));.push_back (ToRU(L «Быстрая»));.push_back (ToRU(L «Шелла»));= 0;= new int[0];= new int[0];= true;

}:~Algo()

{.clear();[] listStart;[] listResult;.clear();.clear();

}Algo:createOperationList (int length, int sort)

{.clear(); // создали пустой список (вектор)(logOn)

{.clear(); // обнулили логи= 0; // обнулили шаги

}*list = new int[length]; // создали пустой список (для чисел)

for (int i=0; i<length; i++) list[i] = listStart[i];(sort)

{1:createSelection (list, length);;2:createBubble (list, length);;3:createInsert (list, length);;4:createQuick (list, length);;5:createShell (list, length);;:;

}

}Algo:createSelection (int l[], int len)

{j = 0; // для запоминания подходящего элемента

int buf = 0; // буфер для элементов(int i=0; i<(len-1); i++)

{= i; // подходящий = первый выдвинутый(«a», i); // выдвинуть i-элемент на 200

pushLog (ToRU(L «Выдвинули число»), Ogre: StringConverter:toString (l[i]),

ToRU (L». Будем сравнивать с ним»));

for (int k=i+1; k<len; k++)

{(«b», k); // выдвинуть k-элемент на 100

pushLog (ToRU(L «Сравним»), Ogre: StringConverter:toString (l[k]),(L» и»), Ogre: StringConverter:toString (l[i]));

if (l[j]>l[k])

{= k; // подходящий = выдвинутый(buf>0)

{(«d», buf); // вернуть на место buf

pushLog (Ogre: StringConverter:toString (l[k]), ToRU (L» >»),: StringConverter:toString (l[j]),

ToRU (L», поэтому дальше будем сравнивать с ним»));

}= j; // запомнили последний подходящий

} else {(«d», k); // вернуть на место k-элемент ot 100

pushLog (Ogre: StringConverter:toString (l[k]), ToRU (L» >=»),: StringConverter:toString (l[i]), (L», поэтому вернем его на место»));

}

}(j>i)

{(«s», i, j); // поменять i и j(Ogre: StringConverter:toString (l[j]), ToRU (L» >»),: StringConverter:toString (l[i]), (L», поэтому поменяем их местами»));

buf = l[i];[i] = l[j];[j] = buf;

push («f», i, j); // вернуть на место 2 элемента(ToRU(L «Вернули элементы на место»));

} else {(«c», i); // вернуть на место i-элемент ot 200

pushLog (Ogre: StringConverter:toString (l[j]), ToRU (L» <=»),: StringConverter:toString (l[i]),

ToRU (L», поэтому вернем его на место»));

}= 0; // обнулили буфер

}= l; // запомнили конечный список

}Algo:createBubble (int l[], int len)

{j = 0; // для запоминания подходящего элемента

int buf = 0; // буфер для элементов(int i=0; i<len; i++)

{(int k=(len-1); k>i; k-)

{(«e», k-1, k); // выдвинуть 2 элемента

pushLog (ToRU(L «Сравним числа»),

Ogre: StringConverter:toString (l[k]),(L» и»), Ogre: StringConverter:toString (l[k-1]));(l[k] < l [k-1])

{(«s», k-1, k); // поменять k-1 и k(Ogre: StringConverter:toString (l[k]), ToRU (L» <»),: StringConverter:toString (l[k-1]), (L», поэтому поменяем их местами»));

buf = l[k];[k] = l [k-1];[k-1] = buf;

pushLog (ToRU(L «Возвратим числа на место»));

} else {(Ogre: StringConverter:toString (l[k]), ToRU (L» >=»),: StringConverter:toString (l[k-1]),

ToRU (L», поэтому возвращаем их на место»));

}(«f», k-1, k); // вернуть на место 2 элемента

}

}= l; // запомнили конечный список

}

void Algo:createInsert (int l[], int len)

{key = 0; // для запоминания выдвинутого элементаi = 0; // для перемещения от выдвинутого элемента до 1 элемента

for (int j = 1; j<len; j++)

{(«a», j); // выдвинуть j-элемент на 200

pushLog (ToRU(L «Выдвинули число»), Ogre: StringConverter:toString (l[j]),

ToRU (L». Будем сравнивать с ним»));= l[j]; // запомнили выдвинутый элемент= j-1; // запомнили положение предыдущего элемента

while ((i>=0) && (l[i]>key))

{(«b», i); // выдвинуть i-элемент на 100

pushLog (ToRU(L «Сравним»), Ogre: StringConverter:toString (l[i]),(L» и»), Ogre: StringConverter:toString (l[i+1]));(«s», i, i+1); // поменять i и key(Ogre: StringConverter:toString (l[i+1]), ToRU (L» <»),: StringConverter:toString (l[i]), (L», поэтому поменяем их местами»));

l [i+1] = l[i];= i-1;[i+1]=key; («c», i+2); // вернуть на место i+1-элемент ot 200

pushLog (ToRU(L «Вернем его на место»),

Ogre: StringConverter:toString (l[i+2]), (L», а дальше будем сравнивать с»),

Ogre: StringConverter:toString (l[i+1]));

}

push («b», i); // выдвинуть i-элемент на 100

pushLog (ToRU(L «Сравним»), Ogre: StringConverter:toString (l[i]),(L» и»), Ogre: StringConverter:toString (l[i+1]));

push («f», i, i+1); // вернуть на место 2 элемента

pushLog (Ogre: StringConverter:toString (l[i+1]), ToRU (L» >=»),: StringConverter:toString (l[i]),

ToRU (L», поэтому возвращаем их на место»));

}= l; // запомнили конечный список

}

void Algo:createQuick (int l[], int len)

{<int> lvec(0); // создали вектор для копирования последовательности

for (int i=0; i<len; i++)

{.push_back (l[i]); // копируем последовательность в вектор

}= quickSort (lvec, len, 0); // запустили сортировку с 0 элемента

for (int i=0; i<len; i++)

{[i] = lvec[i]; // копируем конечный вектор в список

}= l; // запомнили конечный список

}

vector<int> Algo:quickSort (vector<int> data, int const len, int p)

{<int> l = data; // скопировали исходный вектор

int const lenD = len; // запомнили длину

int pivot = 0; // создали опорный элементind = lenD/2; // запомнили центральную точку в последовательностиindVec = ind; // запомнили центральную точку для вектораdecIndVec = 0; // сколько раз уменьшали indVecj = 0, k = 0; // j/k - количество получаемых элементов слева / справа

if (lenD>1) {<int> L(0); // левый массив

vector<int> R(0); // правый массив= l[ind]; // запомнили опорный элемент(«a», indVec+p); // выдвинуть опорный-элемент на 200

pushLog (ToRU(L «Выдвинули число»), Ogre: StringConverter:toString (l[ind]),

ToRU (L». Будем сравнивать с ним»));

for (int i=0; i<lenD; i++)

{(i!=ind)

{(«b», i+p-decIndVec); // выдвинуть i-элемент на 100(ToRU(L «Сравним»), Ogre: StringConverter:toString (l[i]),(L» и»), Ogre: StringConverter:toString (l[ind]));((l[i]<pivot))

{.push_back (l[i]); // заполняем левый массив

j++; // увеличили количество элементов слева(i<ind)

{(«d», i+p-decIndVec); // вернуть на место i-элемент

pushLog (Ogre: StringConverter:toString (l[i]), ToRU (L» <»),: StringConverter:toString (l[ind]), (L», поэтому вернем его на место»));

} else {

push («q», i+p-decIndVec, indVec+p); // двинуть 1 элемент

pushLog (Ogre: StringConverter:toString (l[i]), ToRU (L» <»),: StringConverter:toString (l[ind]),

ToRU (L», поэтому поставим его перед опорным в конец левого массива»));(«d», indVec+p); // вернуть на место i-элемент

pushLog (ToRU(L «Вернем»),: StringConverter:toString (l[i]), (L» на место»));++;

}

} else {.push_back (l[i]); // заполняем правый массив++; // увеличили количество элементов справа(i>ind)

{(«d», i+p-decIndVec); // вернуть на место i-элемент

pushLog (Ogre: StringConverter:toString (l[i]), ToRU (L» >=»),: StringConverter:toString (l[ind]), (L», поэтому вернем его на место»));

} else {

push («r», i+p-decIndVec, indVec+p+k-1); // двинуть 1 элемент

pushLog (Ogre: StringConverter:toString (l[i]), ToRU (L» >=»),: StringConverter:toString (l[ind]),

ToRU (L», поэтому поставим его после опорного в конец правого массива»));(«d», indVec+p+k-1); // вернуть на место i-элемент

pushLog (ToRU(L «Вернем»),: StringConverter:toString (l[i]), (L» на место»));

decIndVec++;

indVec -;

}

}

} else {

decIndVec = 0;

}

}

push («c», indVec+p); // вернуть на место опорный-элемент ot 200

pushLog (ToRU(L «Вернем»), Ogre: StringConverter:toString (l[ind]),

ToRU (L» на место»));= quickSort (L, j, p); // сортируем элементы слева= quickSort (R, k, indVec+1+p); // сортируем элементы справа

for (int cnt=0; cnt<lenD; cnt++)

{(cnt<j)

{[cnt] = L[cnt]; // заполняем вектор левыми элементами

}if (cnt==j)

{[cnt] = pivot; // вставили опорный элемент

} else {[cnt] = R [cnt - (j+1)]; // заполняем вектор правыми элементами

}

}

}l; // вернули полученный вектор

}

void Algo:createShell (int l[], int len)

{temp = 0; // для запоминания сравниваемого элементаind = 0; // для запоминания, какой номер сейчас вывинут

for (int gap = len/2; gap > 0; gap /= 2)

{(int i=gap; i<len; i++)

{temp = l[i];= i;

push («a», i); // выдвинуть i-элемент на 200

pushLog (ToRU(L «Выдвинули число»),

Ogre: StringConverter:toString (l[i]),

ToRU (L». Будем сравнивать с ним»));

int j;(j = i; j >= gap; j -= gap)

{(«b», j-gap); // выдвинуть j-элемент на 100

pushLog (ToRU(L «Сравним»),: StringConverter:toString (l[j-gap]),(L» и»), Ogre: StringConverter:toString(temp));(l [j - gap] > temp)

{(«s», j-gap, ind); // swap j-gap элемент & temp(Ogre: StringConverter:toString (l[j-gap]),(L» >»),: StringConverter:toString (l[j]), (L», поэтому поменяем их местами»));

l[j] = l [j - gap];= j-gap;

push («d», j); // вернуть на место ot 100

pushLog (ToRU(L «Вернем»),: StringConverter:toString (l[j-gap]), ToRU (L» на место»));

} else {(«d», j-gap); // вернуть на место ot 100

pushLog (Ogre: StringConverter:toString (l[j-gap]),(L» <=»),: StringConverter:toString (l[j]), (L», поэтому вернем его на место»));

j = 0;

}

}[ind] = temp;(«c», ind); // вернуть на место опорный-элемент ot 200

pushLog (ToRU(L «Вернем»), Ogre: StringConverter:toString (l[ind]),(L» на место»));

}

}= l;

}Algo:push (string oper, int num)

{+= «»;+= Ogre: StringConverter:toString(num);.push_back(oper);(logOn)++;

}Algo:push (string oper, int num1, int num2)

{+= «»;+= Ogre: StringConverter:toString(num1);+= «»;+= Ogre: StringConverter:toString(num2);.push_back(oper);(logOn) stepSum++;

}Algo:pushLog (CEGUI: String l1)

{(logOn) logSort.push_back(l1);

}Algo:pushLog (CEGUI: String l1, CEGUI: String l2)

{(logOn)

{+= l2;.push_back(l1);

}

}Algo:pushLog (CEGUI: String l1, CEGUI: String l2, CEGUI: String l3)

{(logOn)

{+= l2;+= l3;.push_back(l1);

}

}Algo:pushLog (CEGUI: String l1, CEGUI: String l2, CEGUI: String l3, CEGUI: String l4)

{(logOn)

{+= l2;+= l3;+= l4;.push_back(l1);

}

}Algo:pushLog (CEGUI: String l1, CEGUI: String l2, CEGUI: String l3, CEGUI: String l4, CEGUI: String l5)

{(logOn)

{+= l2;+= l3;+= l4;+= l5;.push_back(l1);

}

}

Листинг файла MainApp.h

#include «BaseApp.h»

#include «ListMember.h»

#include «CubeMember.h»

#include «Algo.h»

#include «Convert.h»

#include «GUI.h»

#include <iostream>

#include <vector>

#include <time.h>

#include <stdlib.h>

#include <CEGUI.h>

#include <RendererModules/Ogre/CEGUIOgreRenderer.h>

namespace std;namespace Convert;

MainApp: public BaseApp

{:(void);~MainApp(void);:listLength, step;*listStart;*list;*listCube;idSort;<string>operation;: StringlogAlgo;timerEnabled;timerPoint;shadow;cam;algo;gui;: OgreRenderer* mRenderer;: Entity*groundEntity; // сущность для поверхности

void createScene(void); // для создания сценыbool frameRenderingQueued (const Ogre: FrameEvent& fe);bool keyPressed (const OIS: KeyEvent& ke);bool keyReleased (const OIS: KeyEvent& ke);void listCreate(); // для построения и создания list on scenevoid createListStart (int listIn[]); // для построения исходного спискаvoid createListMember (int listIn[]); // для построения списка ListMember

virtual void createListCube(); // для построения и создания кубиков

virtual void deleteListCube(); // for delete cubes on scene

virtual void setCubePosition(); // для настройки позиций кубиковvoid setShadow(); // для включения / выключения тени от кубиков

virtual void createSort();void nextStepSort();void lastStepSort();void nextStep();void lastStep();void stopStep(); // stop allvoid timerOn();void timerOff();void animMoveFront1 (int num, int point); // двигаем куб на себяvoid animMoveBack1 (int num); // двигаем куб на местоvoid animMoveFront2 (int num1, int num2); // двигаем 2 куба на себяvoid animMoveBack2 (int num1, int num2); // двигаем 2 куба на местоvoid animSwap12 (int num1, int num2);void animSwap21 (int num1, int num2);void animSwap2 (int num1, int num2);void createFrameListener(void);bool mouseMoved (const OIS: MouseEvent &arg);bool mousePressed (const OIS: MouseEvent &arg, OIS: MouseButtonID id);bool mouseReleased (const OIS: MouseEvent &arg, OIS: MouseButtonID id);void createGUIEvents(void); // настраивает указателиquit (const CEGUI: EventArgs &e);camMove();camSetPosition (int x, int y, int z);camDefault(void); // set default cameracam1 (const CEGUI: EventArgs &e);cam2 (const CEGUI: EventArgs &e);cam3 (const CEGUI: EventArgs &e);cam4 (const CEGUI: EventArgs &e);listAuto (const CEGUI: EventArgs &e);listOk (const CEGUI: EventArgs &e);algoOff (const CEGUI: EventArgs &e);algoL (const CEGUI: EventArgs &e);algoR (const CEGUI: EventArgs &e);stepStop (const CEGUI: EventArgs &e);stepPlay (const CEGUI: EventArgs &e);stepPause (const CEGUI: EventArgs &e);stepLast (const CEGUI: EventArgs &e);stepNext (const CEGUI: EventArgs &e);speedOn (const CEGUI: EventArgs &e);speedOff (const CEGUI: EventArgs &e);speedReportOk (const CEGUI: EventArgs &e);sceneOn (const CEGUI: EventArgs &e);sceneOff (const CEGUI: EventArgs &e);sky1 (const CEGUI: EventArgs &e);sky2 (const CEGUI: EventArgs &e);sky3 (const CEGUI: EventArgs &e);ground1 (const CEGUI: EventArgs &e);ground2 (const CEGUI: EventArgs &e);ground3 (const CEGUI: EventArgs &e);shadowOn (const CEGUI: EventArgs &e);shadowOff (const CEGUI: EventArgs &e);

};

Листинг файла MainApp.cpp

#include «MainApp.h»

: MainApp(void)

{= 1;= new ListMember[0];= new CubeMember[0];= 0; // шаг = 0= 1;= false;= 0;= true;= 1;

}:~MainApp(void)

{>getRootSceneNode()->removeAllChildren();[] list;[] listCube;.clear();

}MainApp:createScene(void)

{>setAmbientLight (Ogre: ColourValue (0.5, 0.5, 0.5));>setShadowTechnique (Ogre:SHADOWTYPE_STENCIL_ADDITIVE);();: Plane plane (Ogre: Vector3:UNIT_Y, 0);: MeshManager:getSingleton().createPlane («ground»,: ResourceGroupManager:DEFAULT_RESOURCE_GROUP_NAME,, 150000, 150000, 20, 20, true, 1, 50, 50, Ogre: Vector3:UNIT_Z);= mSceneMgr->createEntity («ground»);>getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);>setCastShadows(false);>setMaterialName («Examples/Asphalt1»); // залили землю материалом: Light* directionalLight = mSceneMgr->createLight («DirectionalLight»);>setType (Ogre: Light:LT_DIRECTIONAL);>setDiffuseColour (Ogre: ColourValue (0.4, 0.5, 0.5));>setSpecularColour (Ogre: ColourValue (0.4, 0.5, 0.5));>setDirection (Ogre: Vector3 (0, -1, 1));>setSkyBox (true, «Examples/MorningSkyBox», 300);= &CEGUI: OgreRenderer:bootstrapSystem(); // инициализировали СЕГУИ: SchemeManager:getSingleton().create («TaharezLook.scheme»);: System:getSingleton().setDefaultMouseCursor («TaharezLook», «MouseArrow»);CEGUI: Window *sheet = gui.createGUI(); // строим ГУИ();: System:getSingleton().setGUISheet(sheet);

}MainApp:createListStart (int listIn[])

{(int i=0; i<listLength; i++)algo.listStart[i] = listIn[i];

}MainApp:createListMember (int listIn[])

{(int i=0; i<listLength; i++)

{[i].value = listIn[i];[i].numCube = i;

}

}MainApp:createListCube()

{(int i=0; i<listLength; i++)

{[i].entity = mSceneMgr->createEntity («Cube.mesh»);[i].entity->setMaterialName («Examples/colorBlue»);[i].node = mSceneMgr->getRootSceneNode()->createChildSceneNode();[i].node->setScale (1, (list[i].value*0.1), 1);[i].node->attachObject (listCube[i].entity);

}(); // настраиваем позиции(); // настраиваем shadow(); // подвинули камеру

}MainApp:deleteListCube()

{(int i=0; i<listLength; i++)>getRootSceneNode()->removeChild (listCube[i].node);

}MainApp:setCubePosition()

{(int i=0; i<listLength; i++)[i].node->setPosition((i*120), (list[i].value*5), 0);

}MainApp:setShadow()

{(int i=0; i<listLength; i++)[i].entity->setCastShadows(shadow); // set shadow.shadowOn->setEnabled(! shadow);.shadowOff->setEnabled(shadow);

}MainApp:createSort()

{= false; // остановили таймер, мало ли он включен

algo.logOn = true; // включили логирование в алго

algo.createOperationList (listLength, idSort);= algo.vec; // собрали список операций= 0; // обнулили шаг(algo.listStart); // собрали исходный список(); // настроили позиции кубиков.algoText->setText (algo.algoName [idSort-1]);.stepEnableBegin(); // разблокировали шаги= ToRU (L «Построен алгоритм Сортировка»);+= algo.algoName [idSort-1];.logText->setText(logAlgo);

}MainApp:nextStepSort()

{'a': // a - выдвинуть 1 элемент на 200(elem[0], 200); // двигаем 1 куб на себя

break;'b': // b - выдвинуть 1 элемент на 100

animMoveFront1 (elem[0], 100); // двигаем 1 куб на себя;

case 'c': // c - вернуть на место 1 элементт ot 200'd': // d - вернуть на место 1 элементт ot 100(elem[0]); // двигаем 1 куб на место;'e': // выдвинуть 2 элемента(elem[0], elem[1]); // двигаем 2 куба на место;'f': // вернуть на место 2 элемента(elem[0], elem[1]); // двигаем 2 куба на место;'q': // двинуть 1 элемент на место перед 2 элементом(elem[0], elem[1]);;'r': // двинуть 1 элемент на место за 2 элементом

animSwap21 (elem[0], elem[1]);;'s': // s - поменять 2 элемента

animSwap2 (elem[0], elem[1]); // меняем местами 2 куба

break;:;

}(step==(algo.stepSum - 1))

{.logText->setText (ToRU(L «Сортировка завершена!»));

} else {.logText->setText (algo.logSort[step]);

}++; // увеличили шаг на 1

}MainApp:lastStepSort()

{-; // уменьшили шаг на 1:string oper = operation[step]; // запомнили этот шаг<int> elem = ToListInt(oper);(oper[0])

{'a': // a - выдвинуть 1 элемент на 200'b': // b - выдвинуть 1 элемент на 100

animMoveBack1 (elem[0]); // двигаем 1 куб на место;'c': // c - вернуть на место 1 элементт ot 200

animMoveFront1 (elem[0], 200); // двигаем 1 куб на себя;

case 'd': // d - вернуть на место 1 элементт ot 100

animMoveFront1 (elem[0], 100); // двигаем 1 куб на себя;'e': // e - выдвинуть 2 элемента(elem[0], elem[1]); // двигаем 2 куба на место

break;'f': // f - вернуть на место 2 элемента(elem[1], 200); // двигаем 1 куб на себя(elem[0], 100); // двигаем 1 куб на себя;'q': // двинуть 1 элемент на место перед 2 элементом(elem[1], elem[0]);;'r': // двинуть 1 элемент на место за 2 элементом

animSwap12 (elem[1], elem[0]);;'s': // s - поменять 2 элемента

animSwap2 (elem[0], elem[1]); // меняем местами 2 куба

break;:;

}(step==0)

{.logText->setText (ToRU(L «Список возвращен к исходному состоянию!»));

} else {: String txt = ToRU (L «Отмена действия:»);

txt += algo.logSort[step];.logText->setText(txt);

}

}MainApp:nextStep(void)

{((step < algo.stepSum) && (operation.size()>1))();

}MainApp:lastStep(void)

{((step > 0) && (operation.size()>1))();

}MainApp:stopStep(void)

{= false;();

gui.logText->setText (ToRU(L «Список возвращен к исходному состоянию!»));

}MainApp:animMoveFront1 (int num, int point)

{: Vector3 vec = listCube [list[num].numCube].node->getPosition();(vec.z < point)

{.z += 1;[list[num].numCube].node->setPosition(vec);

}

}MainApp:animMoveBack1 (int num)

{: Vector3 vec = listCube [list[num].numCube].node->getPosition();(vec.z > 0)

{.z -= 1;[list[num].numCube].node->setPosition(vec);

}

}MainApp:animMoveFront2 (int num1, int num2)

{: Vector3 vec1 = listCube [list[num1].numCube].node->getPosition();: Vector3 vec2 = listCube [list[num2].numCube].node->getPosition();(vec1.z < 200)

{.z += 1;[list[num1].numCube].node->setPosition(vec1);(vec2.z < 100)

{.z += 1;[list[num2].numCube].node->setPosition(vec2);

}

}

}MainApp:animMoveBack2 (int num1, int num2)

{: Vector3 vec1 = listCube [list[num1].numCube].node->getPosition();: Vector3 vec2 = listCube [list[num2].numCube].node->getPosition();((vec1.z > 0) || (vec2.z > 0))

{(vec1.z > 0)

{.z -= 1;[list[num1].numCube].node->setPosition(vec1);

}(vec2.z > 0)

{.z -= 1;[list[num2].numCube].node->setPosition(vec2);

}

}

}MainApp:animSwap12 (int num1, int num2)

{: Vector3 vec1 = listCube [list[num1].numCube].node->getPosition();: Vector3 vec2 = listCube [list[num2].numCube].node->getPosition();

int point = vec2.x + 120; // запомнили конечную точку перемещения

int between = num1 - num2;.x = vec2.x;[list[num1].numCube].node->setPosition(vec1);(listCube [list[num2].numCube].node->getPosition().x < point)

{(int i=0; i<between; i++)

{= listCube [list[num2+i].numCube].node->getPosition();.x += 1;[list[num2+i].numCube].node->setPosition(vec2);

}

}buff = list[num1];(int i=between; i>0; i-)[num2+i] = list [num2+i-1];[num2] = buff;

}MainApp:animSwap21 (int num1, int num2)

{: Vector3 vec1 = listCube [list[num1].numCube].node->getPosition();: Vector3 vec2 = listCube [list[num2].numCube].node->getPosition();

int point = vec2.x - 120; // запомнили конечную точку перемещения

int between = num2 - num1;.x = vec2.x;[list[num1].numCube].node->setPosition(vec1);(listCube [list[num2].numCube].node->getPosition().x > point)

{(int i=between; i>0; i-)

{= listCube [list[num2-i+1].numCube].node->getPosition();.x -= 1;[list[num2-i+1].numCube].node->setPosition(vec2);

}

}buff = list[num1];(int i=0; i<between; i++)[num1+i] = list [num1+i+1];[num2] = buff;

}MainApp:animSwap2 (int num1, int num2)

{: Vector3 vec1 = listCube [list[num1].numCube].node->getPosition();: Vector3 vec2 = listCube [list[num2].numCube].node->getPosition();

int point = vec2.x; // запомнили конечную точку перемещения

while (vec1.x < point)

{.x += 1;.x -= 1;[list[num1].numCube].node->setPosition(vec1);[list[num2].numCube].node->setPosition(vec2);

}buff = list[num1];[num1] = list[num2];[num2] = buff;

}MainApp:createFrameListener(void)

{: LogManager:getSingletonPtr()->logMessage («*** Initializing OIS ***»);: ParamList pl;_t windowHnd = 0;:ostringstream windowHndStr;>getCustomAttribute («WINDOW», &windowHnd);<< windowHnd;.insert (std:make_pair (std:string («WINDOW»), windowHndStr.str()));= OIS: InputManager:createInputSystem(pl);= static_cast<OIS: Keyboard*>(mInputManager->createInputObject (OIS:OISKeyboard, true));= static_cast<OIS: Mouse*>(mInputManager->createInputObject (OIS:OISMouse, true));>setEventCallback(this);>setEventCallback(this);(mWindow);: WindowEventUtilities:addWindowEventListener (mWindow, this);>addFrameListener(this);

}MainApp:frameRenderingQueued (const Ogre: FrameEvent& fe)

{(mWindow->isClosed())false;(mShutDown)false;>capture();>capture();: System:getSingleton().injectTimePulse (fe.timeSinceLastFrame);(timerEnabled)

{++;(timerPoint>50)

{();= 0;(step == algo.stepSum)

{.stepEnableEnd();= false;

}

}

}true;

}MainApp:keyPressed (const OIS: KeyEvent& ke)

{: Vector3 camMove = mCamera->getPosition();: Vector3 camRotate = mCamera->getDirection();camView = true;(ke.key)

{OIS:KC_P:OIS:KC_ESCAPE:= true;;OIS:KC_W:.z -= 100;;OIS:KC_S:.z += 100;;OIS:KC_A:.x -= 100;;OIS:KC_D:.x += 100;;OIS:KC_Q:.y -= 100;;OIS:KC_E:.y += 100;;OIS:KC_I:.z -= 0.05;(camRotate.z==-1).z = 1;;OIS:KC_K:.z += 0.05;(camRotate.z==1).z = -1;;OIS:KC_J:.x -= 0.05;(camRotate.x==-1).x = 1;;OIS:KC_L:.x += 0.05;(camRotate.x==1).x = -1;;OIS:KC_U:.y -= 0.05;(camRotate.y==-1).y = 1;;OIS:KC_O:.y += 0.05;(camRotate.y==1).y = -1;;:= false;;

}(camView)

{>setPosition(camMove); // настроили камеру>setDirection(camRotate); // rotate камеру

}: System &sys = CEGUI: System:getSingleton();.injectKeyDown (ke.key);.injectChar (ke.text);true;

}MainApp:keyReleased (const OIS: KeyEvent& ke)

{: System:getSingleton().injectKeyUp (ke.key);true;

}: MouseButton convertButton (OIS: MouseButtonID buttonID)

{(buttonID)

{OIS:MB_Left:CEGUI: LeftButton;OIS:MB_Right:CEGUI: RightButton;OIS:MB_Middle:CEGUI: MiddleButton;:CEGUI: LeftButton;

}

}MainApp:mouseMoved (const OIS: MouseEvent &arg)

{: System &sys = CEGUI: System:getSingleton();.injectMouseMove (arg.state.X.rel, arg.state.Y.rel);(arg.state.Z.rel).injectMouseWheelChange (arg.state.Z.rel / 120.0f);true;

}MainApp:mousePressed (const OIS: MouseEvent &arg, OIS: MouseButtonID id)

{: System:getSingleton().injectMouseButtonDown (convertButton(id));true;

}MainApp:mouseReleased (const OIS: MouseEvent &arg, OIS: MouseButtonID id)

{: System:getSingleton().injectMouseButtonUp (convertButton(id));true;

}MainApp:createGUIEvents(void)

{.quit->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:quit, this));.cam1->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:cam1, this));.cam2->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:cam2, this));.cam3->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:cam3, this));.cam4->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:cam4, this));.algoOff->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:algoOff, this));.algoL->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:algoL, this));.algoR->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:algoR, this));.listOk->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:listOk, this));.listAuto->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:listAuto, this));.stepStop->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:stepStop, this));.stepPlay->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:stepPlay, this));.stepPause->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:stepPause, this));.stepLast->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:stepLast, this));.stepNext->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:stepNext, this));.speedOn->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:speedOn, this));.speedOff->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:speedOff, this));.speedReportOk->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:speedReportOk, this));.sceneOn->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:sceneOn, this));.sceneOff->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:sceneOff, this));.sky1->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:sky1, this));.sky2->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:sky2, this));.sky3->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:sky3, this));.ground1->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:ground1, this));.ground2->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:ground2, this));.ground3->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:ground3, this));.shadowOn->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:shadowOn, this));.shadowOff->subscribeEvent (CEGUI: PushButton: EventClicked, CEGUI: Event: Subscriber (&MainApp:shadowOff, this));

}MainApp:quit (const CEGUI: EventArgs &e)

{= true;true;

}MainApp:camMove(void)

{(cam)

{1:();;2:(100, 900, 1800); // настроили position>setDirection (-0.05, -0.5, -0.85); // rotate камеру;3:(700, 500, 1300); // настроили position>setDirection (-0.4, -0.4, -0.8); // rotate камеру;4:(100, 300, 1700); // настроили position>setDirection (-0.05, -0.2, -0.95); // rotate камеру;:;

}

}MainApp:camSetPosition (int x, int y, int z)

{+= (listLength-1) * 60;>setPosition (x, y, z); // настроили position

}MainApp:camDefault(void)

{(-900, 200, 900); // настроили position>setDirection (0.6, -0.3, -0.75); // rotate камеру

}MainApp:cam1 (const CEGUI: EventArgs &e)

{= 1;();true;

}MainApp:cam2 (const CEGUI: EventArgs &e)

{= 2;();true;

}MainApp:cam3 (const CEGUI: EventArgs &e)

{= 3;();true;

}MainApp:cam4 (const CEGUI: EventArgs &e)

{= 4;();true;

}MainApp:listAuto (const CEGUI: EventArgs &e)

{((unsigned) time(NULL));len = rand()%8 + 3; // length of list 3 to 10<int> x2 (0); // empty list(int i=0; i<len; i++).push_back (rand()%15 + 1); // random 1 to 15.listEdit->setText (ToString(x2));true;

}MainApp:listOk (const CEGUI: EventArgs &e)

{();();true;

}MainApp:listCreate(void)

{<int> vecList = ToListInt (gui.listEdit->getText());= vecList.size(); // задали длину*x2 = new int[listLength]; // создали пустой список нужной длины(int i=0; i<listLength; i++)

{(vecList[i]==0)[i] = 1; // чтобы не показывать нулевое значение[i] = vecList[i]; // переносим числа из вектора в массив

}

algo.listStart = new int[listLength]; // собрали пустой список заданной длины

list = new ListMember[listLength];= new CubeMember[listLength]; // собрали пустой список кубиков

createListStart(x2); // собрали начальный список listStart(x2); // создали список и построили кубики(); // построили кубики.listHide(); // спрятали ввод послед-ти.algoShow(); // показали все для алгоритма

gui.listEdit->setText (ToString(vecList));.speedList->setText (ToString(vecList));.clear(); // очищаем вектор

}MainApp:algoOff (const CEGUI: EventArgs &e)

{(); // чистим кубики на сцене.listShow();.speedHide();.algoHide();.speedReportLog->setText (ToRU(L»!!! Нажмите кнопку Создать для создания отчета о скорости работы алгоритмов!!!»));

gui.speedReportOk->enable();true;

}MainApp:algoL (const CEGUI: EventArgs &e)

{-;(idSort<1) idSort = algo.algoSum;();true;

}MainApp:algoR (const CEGUI: EventArgs &e)

{++;(idSort>algo.algoSum) idSort = 1;();true;

}MainApp:timerOn(void)

{= 0;= true;

}MainApp:timerOff(void)

{= false;

}MainApp:stepStop (const CEGUI: EventArgs &e)

{();true;

}MainApp:stepPlay (const CEGUI: EventArgs &e)

{();.stepEnablePlay();true;

}MainApp:stepPause (const CEGUI: EventArgs &e)

{();.stepEnablePause();true;

}MainApp:stepLast (const CEGUI: EventArgs &e)

{();(step == 0)

{.stepEnableBegin();

} else {.stepEnablePause();

}true;

}MainApp:stepNext (const CEGUI: EventArgs &e)

{();(step == algo.stepSum)

{.stepEnableEnd();

} else {.stepEnablePause();

}

true;

}MainApp:speedOn (const CEGUI: EventArgs &e)

{.speedShow();true;

}MainApp:speedOff (const CEGUI: EventArgs &e)

{.speedHide();true;

}MainApp:speedReportOk (const CEGUI: EventArgs &e)

{: String report = ToRU (L «Скорость работы алгоритмов: \n»);<string> operList;(int i=0; i<algo.algoSum; i++)

{.logOn = false; // выключили логирование в алго

algo.createOperationList (listLength, i+1);= algo.vec;+= algo.algoName[i];+= «-»;+= ToString (operList.size());+= ToRU (L» нс \n»);.clear();

}.speedReportLog->setText(report); // показали репорт

gui.speedReportOk->disable(); // кнопка больше не активна

return true;

}MainApp:sceneOn (const CEGUI: EventArgs &e)

{.sceneShow();true;

}MainApp:sceneOff (const CEGUI: EventArgs &e)

{.sceneHide();true;

}MainApp:sky1 (const CEGUI: EventArgs &e)

{>setSkyBox (true, «Examples/MorningSkyBox», 300);true;

}MainApp:sky2 (const CEGUI: EventArgs &e)

{>setSkyBox (true, «Examples/SpaceSkyBox», 300);true;

}MainApp:sky3 (const CEGUI: EventArgs &e)

{>setSkyBox (true, «Examples/StormySkyBox», 300);true;

}MainApp:ground1 (const CEGUI: EventArgs &e)

{>setMaterialName («Examples/Asphalt1»); // залили землю материаломtrue;

}MainApp:ground2 (const CEGUI: EventArgs &e)

{>setMaterialName («Examples/GrassFloor»); // залили землю материаломtrue;

}MainApp:ground3 (const CEGUI: EventArgs &e)

{>setMaterialName («Examples/MramorCM»); // залили землю материаломtrue;

}MainApp:shadowOn (const CEGUI: EventArgs &e)

{= true;();true;

}MainApp:shadowOff (const CEGUI: EventArgs &e)

{= false;();true;

}

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32

#define WIN32_LEAN_AND_MEAN

#include «windows.h»

#endif

#ifdef __cplusplus«C» {

#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32WINAPI WinMain (HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)

#elsemain (int argc, char *argv[])

#endif

{

// Create application objectapp;

{.go();

} catch (Ogre: Exception& e) {

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32(NULL, e.getFullDescription().c_str(), «An exception has occurred!», MB_OK | MB_ICONERROR | MB_TASKMODAL);

#else:cerr << «An exception has occurred:» <<.getFullDescription().c_str() << std:endl;

#endif

}

return 0;

}

#ifdef __cplusplus

}

#endif

Похожие работы на - Визуализатор алгоритмов с применением трехмерной графики

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!