Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
метод_лаб_КИТ_КЭМ_new.doc
Скачиваний:
6
Добавлен:
06.02.2016
Размер:
640.51 Кб
Скачать

Задание к лабораторной работе №2

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

Лабораторная работа №3

Тема: Программирование изображений на языке PostScript с использованием операторов ветвления и циклов.

Цель работы: освоение принципов и приобретение навыков программирования сложных растровых изображений PostScript с использованием способов ритмических преобразований системы координат и графических свойств.

Методические указания к лабораторной работе

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

12 5 sub

и

{ 12 5 sub }

В первом случае числа 12 и 5 будут помещены в стек и выполнена операция вычитания, а во втором - эти числа и оператор SUB будут помещены в массив, который затем будет занесен в стек. Выполняемому массиву может предшествовать имя, задаваемое в виде литерала, а закрывать его может оператор DEF, который ассоциирует его с именем в текущем словаре.

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

Оператор if:

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

Оператор

Значение

eg

= (равно)

gt

> (больше)

ge

>= (больше или равно)

ne

<> (не равно)

lt

< (меньше)

le

<= (меньше или равно)

Логические операторы: NOT, AND, OR и XOR.

Результат операции сравнения или логической операции - логическое значение TRUE или FALSE.

условие {proc} if

Оператор IF берет из стека логический объект, получаемый в результате вычисления условия, и выполняемый массив. Если значение логического объекта TRUE, то выполняются операции, записанные в этом массиве.

Например:

%%% Определяем переменные

/step 15 def

/rightmargin 450 def

%%% Определяем функцию

/checkmargin {

currentpoint pop % оставляет в стеке координату х текущей точки

rightmargin

gt { % Если число на вершине стека больше 450

0 step % то переходим в начало следующей строки

translate

0 0 moveto

} if % в противном случае ничего не делаем

} def

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

Оператор ifelse:

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

Bool {proc1} {proc2} ifelse

Если значение в вершине стека равно TRUE, выполняется последовательность {PROC1}, иначе - {PROC2}.

Циклы:

В языке PostScript имеется три основных конструкции циклов: простой, с параметром и с условием.

Простой цикл имеет следующую структуру:

<количество повторений> <повторяемая процедура> repeat

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

{pop} repeat

Цикл с параметром напоминает конструкцию цикла FOR в Паскале и имеет следующую структуру:

<начальное значение счетчика цикла>< приращение>< конечное значение счетчика цикла>< повторяемую процедуру> FOR.

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

Следующая строка напечатает звездочку через каждые 15 единиц на странице:

0 15 450 {0 moveto (*) show } for

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

/Helvetica findfont

30 scalefont

setfont

/printword {

0 0 moveto

(PC Magazine) show

} def

200 300 translate

.95 -.05 0 % начало приращения, конец

{setgray printword -1.5 translate} for

1 setgray printword

showpage

Цикл с условием соответствует REPEAT...UNTIL в Паскале и имеет конструкцию: <выполняемая процедура> LOOP.

Процедура выполняется до тех пор, пока в ней не встретится оператор EXIT, который заканчивает циклическое выполнение. Если в повторяемой процедуре нет оператора exit, то цикл будет бесконечным, например:

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

%%% Определение процедур

/pagewidth 8 72 mul def % Ширина страницы

/circle { % Рисование круга

x y radius

0 360 arc

stroke

} def

/new-x { % Новая позиция для следующего. круга

x radius add % Это эквивалентно: х=х+radius

/x exch def } def

/DoLineOfCrle { % Рисуем линию из окружностей

/y exch def % заносим значения из стека в переменные

/radius exch def

/x 0 def

{ % условный цикл рисования окружностей до конца страницы

x pagewidth le % центр нового круга в пределах границы?

{circle new-x} % да - рисуем и вычисляем новую позицию

{exit} % иначе - выход из цикла

ifelse

} loop

} def

%%%% Рисуем две линии кругов

15 200 DoLineOfCrle

45 200 DoLineOfCrle

showpage

Массивы:

PostScript работает со сложными структурами (записями), которые называются одномерными массивами. Они определяются как набор объектов (возможно разного типа), заключенный в квадратные скобки. Так

[ (PC Magazine) 1991 (сор) true]

Операции внутри квадратных скобок выполняются по обычным правилам PostScript, так после вычисления

[(add) 10 5 6 mul add]

получим массив из двух элементов [(add) 40] .

Массив может быть также определен с помощью оператора ARRAY, который берет из стека число и создает массив такой длины.

8 array

Эта строка оставит в стеке массив из 8 элементов. Его элементы - NULL-объекты. Элементы массива нумеруются с нуля, что нужно учитывать при вычислении их индексов.

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

Массивы, строки и словари - всё это примеры объектов сложных типов. Их значения хранятся отдельно от самого объекта (то есть PostScript работает в этом случае не со значением, а с указателем на него).

Для работы с элементами массивов служат операторы PUT и GET.

Оператор PUT берет из стека три аргумента: массив, индекс элемента в массиве и объект. Он помещает объект в массив в позицию, заданную индексом:

/MyArray 12 array def

MyArray 5 (Jerry) put

У оператора GET два аргумента: массив и индекс. Он возвращает в стеке элемент массива с заданным индексом. После выполнения строки

[0 1 2 3 4 5] 5 get

в вершине стека будет число 4.

Оператор LENGTH, возвращает длину массива (то есть число его элементов).

Пример программы. которая распечатывает массив, находящийся в стеке.

/LeftM 60 def

/TmpString 40 string def

/Helvetica findfont

11 scalefont

setfont % задали шрифт

/newln {

currentpoint 15 sub exch pop % y-15

LeftM exch moveto

} def

/printarr { % в стеке массив

/arr exch def % поместить массив в переменную

0 1 % параметры цикла: от шаг

arr length 1 sub % до (ДлинаМассива - 1)

{

arr exch get % следующий элемент

TmpString cvs % преобразуем вго в строков тип

show newln % печатаем и нач. новую строку

} for

} def

%%%%%% Основная программа %%%%%

LeftM 400 moveto % печатаем отсюда

% задаем массив

[(Julia) % строка

15 % число

/SimplName % литерал

[8 3 4] % массив

{NewLN} % исполняемый массив

LeftM % переменная

]

printarr % печатаем его

showpage

Перед каждым выполнением цикла оператор for помещает в стек счетчик, который используется в качестве индекса в строке arr exch get. (В этой строке берется не сам массив из стека, а ссылка на него по имени переменной, поэтому и делается exch).

Результат работы программы:

Julia

15

SimplName

--nostringval--

--nostringval--

60

Как видно из примера обычные действия над массивом в PostScript достаточно утомительны. Так как наиболее частой операцией над массивом в этом языке является применение некоторой процедуры к каждому его элементу, то для этого целесообразно применить специальный оператор цикла FORALL. Предыдущий пример можно записать с его помощью более компактно:

arr {30 string cvs show} forall