КГ_8глава (1024123)
Текст из файла
Примеры использования классов языка C++
Рассмотрим пример графической программы, создающей изображения объектов на основе нескольких простых элементов (рис. 8.1).
Рис. 8.1. Трехмерные объекты в различных ракурсах показа
Используем объектно-ориентированную методологию. Каждый элемент будем считать объектом трехмерного пространства, а несколько таких объектов образовывают модель сложного объекта. Для описания объектов используем классы C++. Процитируем автора языка C++ Б. Страустрапа: "Определите, какие классы вам нужны; предусмотрите полный набор операций для каждо-
[ го класса; опишите общие черты явным образом, используя наследова-
! ние" [24].
Сложный пространственный объект в нашей программе построим с использованием таких элементов: куб, сфера и пирамида. Фундамент и колонны бу-
дем считать производными элементами, их определим как множество кубов, специальным образом располагающихся в пространстве (рис. 8.2).
Рис. 8.2. Иерархия классов
В качестве базового элемента определим абстрактный класс фигуры с такими свойствами: размер, цвет, расположение в пространстве, описываемое координатами ее центра. Также предусмотрим для фигур возможность перемещения, изменения размера, цвета и возможность быть нарисованной. Такие общие свойства выразим в классе shape. В этом классе также предусмотрим операцию преобразования координат для отображения в определенной проекции (функция-член PrepareVertex).
Теперь обсудим способ отображения объектов. Поскольку у нас есть элементы-многогранники (куб и пирамида), то можно было бы использовать достаточно быстродействующую функцию Polygon API Windows для рисования граней. А удаление невидимых точек осуществлять сортировкой граней по глубине. Однако такой способ отображения в нашем случае не приемлем, Чуть позже мы покажем почему, а пока что обсудим довольно интересные нюансы объектно-ориентированного стиля программирования. Если бы у нас все объекты были многогранниками, то сортировка граней по глубине означала бы определенную последовательность рисования граней. Например,) сначала одну грань одного объекта, потом соответствующую грань другого \ объекта и так далее. Последовательность рисования в этом случае должна быть от самых дальних граней к самым близким. Однако это усложняет объектно-ориентированную реализацию программы, поскольку желательно было бы, чтобы объект был самодостаточным с точки зрения каждой операции, | выполняемой над ним, — а это невозможно, так как операция сортировки граней должна обеспечивать доступ к отдельным граням, а не только к объекту в целом. Хотя объектно-ориентированная методология не накладывает столь жестких ограничений на реализацию объектов, однако, такое нарушение самодостаточности (инкапсуляции) выглядит не очень эстетично.
Поскольку среди элементов кроме многогранников есть сфера, то метод сор- j тировки граней по глубине нельзя использовать, так как сфера — это не мно- j
гогранник, и она рисуется по пикселам (хотя можно было бы определить ее как многогранник, закрашенный, например, по методу Гуро, однако это намного сложнее, и в данном примере программы не рассматривается). Необходимо использовать Z-буфер, а функция Polygon его не поддерживает. Более того, в составе функций API Windows нет ни одной функции рисования, рассчитанной на использование Z-буфера. Такие функции мы вынуждены сконструировать сами. Относительно объектной ориентированности— метод Z-буфера позволяет полностью инкапсулировать операцию рисования объекта в виде одной функции-члена (мы ее назовем :: Draw). Один вызов функции Draw обеспечивает полный цикл отображения объекта соответствующего класса.
Текст программы (studex34. срр):
Скомпилируйте и запустите программу studex34. Необходимо предупредить, что цикл показа может затянуться надолго. В программе выполняется полный оборот камеры на 360 градусов с шагом в один градус. Время создания и отображение всех 361 кадров в соответствующих ракурсах на компьютере с процессором AMD K6-2, 300 МГц, в 24-битном видеорежиме составляло 807 секунд. То есть, на один кадр расходуется в среднем 807/361 = 2.24 секунды. Размеры окна не изменялись после запуска программы, это отвечает размерам изображения 392 на 239 пикселов. Необходимо признать, что эта программа демонстрирует черепашью скорость рендеринга.
8.1. Анализ и оптимизация программы
Каждую программу можно усовершенствовать. Можно попробовать уменьшить текст программы, уменьшить размер выполняемого файла, улучшить структурированность, модульность и так далее. В данном случае мы попытаемся повысить скорость рендеринга — уменьшить время формирования кадров изображения.
Как оптимизировать программу по быстродействию? Для этого необходимо выполнить анализ работы программы. В результате анализа нужно обнару-
жить операции, которые обуславливают быстродействие программы. Пос^ того как будут найдены критические места программы, можно сделать выв^ ды относительно конкретных путей оптимизации.
Для измерения времени выполнения операций в программе для Window можно воспользоваться функцией API GetLocalTime :
Необходимо предупредить, что миллисекунды измеряются не очень точно, поэтому для повышения точности измерения для некоторой отдельной операции можно делать цикл из многих (сотен, тысяч, ...) одинаковых операций (если вспомогательные операции создания цикла сами по себе не длительные). Кроме того, различные сеансы измерений могут давать различные значения, поэтому необходимо как-то усреднять результаты. Понятно, что все] измерения должны выполняться на одном и том же компьютере и обязатель-; но в одинаковых условиях выполнения программы. Также необходимо учи- ? тывать, что в полночь измерение времени может дать ошибку, — если переход на 0 часов случится в ходе измерений. Впрочем, я и не рекомендую вам по ночам засиживаться за компьютером — ночью надо спать.
Теперь приступим к анализу программы studex34. Вся работа по созданию объектов, их отображение в различных ракурсах и уничтожение объектов делается в теле функции DrawstudyExampie. Сделаем измерения времени ос-
новных операций. На создание объектов, открытие контекста, подготовку битмапа двойного буфера и создание Z-буфера расходуется менее десяти миллисекунд (измерения с точностью до процентов секунд дают 0.00). Таким образом, в ходе дальнейшего анализа сосредоточимся на цикле создания 361 кадра.
Как измерить время, расходуемое во всех 361 кадрах на выполнение функции ciearMyZbuf f er () ? Это сделаем способом, который можно назвать "способом контрольно-измерительного стенда". Такой "стенд" можно сделать на основе текста нашей программы, например, следующим образом:
//далее вычисляем разность в секундах и выводим результат
Разумеется, подобный способ измерений можно считать корректным лишь тогда, когда время выполнения функции CiearMyZbuffer () значительно больше, чем время выполнения операций организации цикла по j.
Время выполнения 361 операции ciearMyZbuffer составляет в среднем 2.1 секунды. Аналогично можно сделать измерения для PatBit— 0.06 сек., SetCameraviewMatrix — 0.00 сек., BitBit — 0.5 сек. Однако делать измерения времени для цикла отображения объектов таким "стендовым" способом нельзя. Для корректного создания изображения обязательно выполнение всех подготовительных операций в полном объеме. Для измерений времени здесь можно предложить другой способ. Суть его такова. Вначале измеряем время выполнения полного цикла создания изображений:
5
А потом исключаем анализируемую операцию:
и измеряем время выполнения без нее. Полный цикл — 807 сек., без исключенной операции — 2.6 сек. Назовем такой способ "временным исключением". Необходимо заметить, что цифру 2.6 можно было бы получить и иначе, если от времени полного цикла вычесть уже измеренное время других операций. Однако способ "временного исключения" предназначен в первую оче-j редь для тех случаев, когда измерение всех составных операций затруднено или не нужно. Продолжим измерения дальше.
Как мы видим, в цикле создания кадров на подготовительные операции расходуется мало времени в сравнении с отображением объектов. В ходе отображения объектов выполняется много операций. Какая из них самая длительная? Осуществим поиск способом "временного исключения". Однако для применения этого способа есть много ограничений. Сформулируем основные условия корректного использования данного способа.
Характеристики
Тип файла документ
Документы такого типа открываются такими программами, как Microsoft Office Word на компьютерах Windows, Apple Pages на компьютерах Mac, Open Office - бесплатная альтернатива на различных платформах, в том числе Linux. Наиболее простым и современным решением будут Google документы, так как открываются онлайн без скачивания прямо в браузере на любой платформе. Существуют российские качественные аналоги, например от Яндекса.
Будьте внимательны на мобильных устройствах, так как там используются упрощённый функционал даже в официальном приложении от Microsoft, поэтому для просмотра скачивайте PDF-версию. А если нужно редактировать файл, то используйте оригинальный файл.
Файлы такого типа обычно разбиты на страницы, а текст может быть форматированным (жирный, курсив, выбор шрифта, таблицы и т.п.), а также в него можно добавлять изображения. Формат идеально подходит для рефератов, докладов и РПЗ курсовых проектов, которые необходимо распечатать. Кстати перед печатью также сохраняйте файл в PDF, так как принтер может начудить со шрифтами.