Главная > Разное > Принципы программирования в машинной графике
<< Предыдущий параграф
Следующий параграф >>
<< Предыдущий параграф Следующий параграф >>
Макеты страниц

2.6. АВТОМАТИЧЕСКИЙ ПОДБОР РАЗМЕРОВ И ПОЗИЦИИ

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

1) объект будет вычерчиваться целиком, так что отсечение не понадобится;

2) окно будет определено расчетом, а не задано заранее;

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

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

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

Тогда расчетными значениями параметров окна будут

Заметим, что крайние точки объекта располагаются на границах окна, чего не было в случае, рассмотренном в параграфе 2.4.

Рис. 2.12. Объект, подлежащий масштабированию

Чтобы предусмотреть некоторое свободное пространство со всех сторон экрана или листа бумаги, необходимо задать размеры области вывода несколько меньше, чем они могли быть на самом деле. Например, можно задать вместо 0.0. Область вывода будет полностью определена при выборе

Как в параграфе 2.4, выполним расчет коэффициентов масштабирования:

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

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

Теперь для любой точки объекта позиция отображаемой точки ( рассчитывается по формулам

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

где пара определяет координаты точки, в которую должнс перемещаться перо, а параметр code может принимать значение 0 или 1, означающее состояние пера “поднято” или “опущено’ соответственно. Другими словами,

где экранные координаты, соответствующие мировые

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

В программе генерацию кривой будем начинать с точки начала координат и перемещаться каждый раз на одну единицу расстояния. Всегда существует текущее направление и текущий угол поворота а. В исходном состоянии оба эти значения равны нулю. Перед каждым шагом угол а увеличивается на случайно выбранное значение угла в пределах от -6° до (целое число). Полученный новый угол поворота добавляется к текущему направлению для получения нового направления. Ограничим максимальное значение кривизны и уменьшим шанс для вырождения в окружность. Для этого модифицируем описанный алгоритм и будем задавать значение 0 для угла а каждый раз, когда его абсолютное значение превышает 15°. Тогда получим следующую программу:

(см. скан)

(см. скан)

В функции direction показано обращение к функции инициализации датчика случайных чисел srand. Ее аргумент seed определяет начальное значение для генерации случайных чисел. Функция time применяется для присвоения значения аргументу seed, зависящему от текущего времени. Таким образом будут генерироваться различные кривые при каждом новом запуске программы. Функция rand выдает большое неотрицательное целое число. Оно преобразуется в целое число в диапазоне от 0 до 12 путем использования остатка от деления на 13, то есть

Другие новые аспекты применения языка Си относятся к операциям ввода и вывода. Для большинства функций ввода/вывода в программу необходимо вставлять директиву которая осуществляет “включение” файла стандартных заголовков функций ввода/вывода. В языке Си различается форматированный и неформатированный ввод/вывод. Наиболее часто используются следующие функции:

(см. скан)

Форматированный ввод/вывод имеет дело с читаемыми символами: имеется структура строк, аналогичная строкам на печатной странице. Неформатированные данные имеют такую же структуру, как они записаны в памяти. Например, целые числа представляются фиксированным количеством битов. В нашем случае с целью повышения эффективности был использован неформатированный ввод/вывод. Файл “открывается” обращением к функции Вторым аргументом может быть либо строка для инициирования считывания, либо строка для записи. (Для неформатированного ввода/вывода некоторые компиляторы требуют задания иных строк вместо или Переменная обозначает структуру, содержащую три числа: х, у и которые будут записываться в файл. “Указатель” на эту переменную является первым аргументом для функции Запись можно рассматривать как обозначение адреса переменной Второй аргумент, равен размеру одной структуры третий аргумент, равный 1, означает количество структур, подлежащих записи. Четвертым аргументом, является указатель файла, полученный из обращения к функции Теперь можно рассмотреть общую программу, которая будет считывать тройки, определять размеры окна, выполнять пересчет мировых координат в экранные координаты и, наконец, вычерчивать картинку в пределах заданной области вывода. Также вычерчиваются небольшие уголки в углах области вывода и точка в середине нижней границы, так что абстрактную картинку можно ориентировать относительно верха и низа (если точка и уголки нежелательны, их легко можно исключить).

Заметим, что в этой программе файл открывается дважды. Операции закрытия и открытия приводят к “перемотке” файла к началу.

(см. скан)

(см. скан)

(см. скан)

Аргументами функции init_viewport являются указатели. Обозначение означает, что имеет тип так что будет иметь тип pointer to float (указатель на Унарные операторы и являются взаимно обратными, так что Результат работы программы показан на рис. 2.13.

Рис. 2.13. Результат работы программ и GENPLOT

<< Предыдущий параграф Следующий параграф >>
Оглавление