Методика разработки сцен на PostScript Урок 3 | Занятие третьеКривыеДля построения реального изображения одних отрезков прямых линий явно недостаточно. Поэтому в PostScript для построения нужных кривых, окружностей и дуг окружностей имеется ряд операторов. Во-первых, оператор arc. Он добавляет окружность к текущей траектории и требует наличия в стеке пяти аргументов:
Угол строится против часовой стрелки:
100 100 42 30 110 arc
Аналогичный arc оператор arcn строит угол по часовой стрелке. Сравните:
100 100 42 30 110 arcn
Эти операторы ведут себя несколько иначе, если уже существует точка текущей траектории -- тогда дуга соединяется с ней прямой линией. Сравните:
newpath
150 200 60 30 150 arc
stroke
и
newpath
150 200 moveto
150 200 60 30 150 arc
stroke
Чтобы нарисовать окружность, нужно задать arc угол в 360 градусов, например:
150 200 60 0 360 arc
Попробуйте, используя оператор arc, нарисуйте произвольную ромашку с 4, 6 и 9 лепестками. Напишите процедуру, аргументом которой будет число лепестков. Эллипсы можно получить, изменяя при рисовании окружности масштабы по осям координат. Напишите программу, в которой это используется. Сглаживание угловПересекающиеся линии часто бывает необходимо соединить плавной кривой. В PostScript для этого существует удобный оператор arcto. В качестве операндов ему в стеке задаются координаты двух точек и радиус, т. е.:
x1 y1 x2 y2 r arcto
Он рисует сегмент прямой линии от текущей точки по направлению к точке х1, у1, а затем дугу до её пересечения со второй прямой. arcto возвращает в стеке координаты начала и конца дуги. Если они не нужны, то эти числа следует удалить из стека:
4 {pop} repeat
Используя оператор arcto, нарисуем какую-нибудь карточку:
/clearstack {
4 { pop } repeat
} def
200 300 translate
0 20 moveto
0 72 108 72 20 arcto
clearstack
108 72 108 0 20 arcto
clearstack
108 0 0 0 20 arcto
clearstack
0 0 0 72 20 arcto
clearstack
fill
0.5 setgray
80 45 20 0 360 arc
fill
/Helvetica findfont
25 scalefont
setfont
30 50 moveto
(My Card) show
showpage
Условные переходыВведем понятие выполняемого массива. Это более формальное название объекта, который ранее был назван процедурой. Какая разница для PostScript между строками:
12 5 sub
и
{ 12 5 sub }
В первом случае числа 12 и 5 будут помещены в стек и будет выполнена операция вычитания, а во втором -- эти числа и оператор sub будут помещены в массив, который затем будет занесен в стек. Выполняемому массиву может предшествовать имя, задаваемое в виде литерала, а закрывать его может оператор def, который ассоциирует его с именем в текущем словаре. Выполняемый массив может использоваться также в некоторых управляющих операторах, таких как repeat. В этом случае выполняемый массив содержит операции, которые будут иметь место, когда выполнятся условия для условного оператора. Оператор ifПрежде чем рассмотреть этот популярный во всех процедурных языках оператор, посмотрим, как записываются операции сравнения чисел. В PostScript, напоминаю, операторы сравнения следуют за сравниваемыми величинами.
Логические операторы: not and or и xor. Результат операции сравнения или логической операции -- логическое значение true или false. Оператор if берет из стека логический объект и выполняемый массив. Если значение логического объекта true, то выполняются операции, записанные в этом массиве. Например:
%%% Определяем переменные
/step 15 def
/rightmargin 450 def
%%% Определяю функцию
/checkmargin {
currentpoint pop % оставляет в стеке х
rightmargin
gt { % Если число на вершине стека больше 450
0 step % то это и выполняем
translate
0 0 moveto
} if % в противном случае ничего не делаем
} def
Процедура получает координату текущей точки и сравнивает её со значением правой границы рабочего поля. Если условие выполняется, то происходит перенос начала координат на следующую строку. Оператор ifelseПозволяет выбрать в зависимости от условия выполнение одной или другой последовательности операторов. Его формат:
условие {ор.1} {op.2} ifelse
Если результат выполнения условия true, выполняется последовательность {op.1}, иначе -- {op.2}. У попа была собакаЭта фраза замечательна тем, что мы с детства получаем представление о рекурсии. PostScript поддерживает рекурсивный вызов процедур, т. е. когда процедура вызывает сама себя. Классический пример -- вычисление факториала:
/factorial { % в стеке n
dup 1
gt {
dup 1
sub
factorial
mul
} if
} def
% вызов
5 factorial
cvs show
Новый оператор cvs преобразует число из вершины стека и помещает его в заданную строку. Дело в том, что оператор show может печатать только строки. Кроме чисел, cvs преобразует и логические величины -- они заменяются в зависимости от значения словами true или false. Вот пример процедуры, печатающей целое число из стека:
/printint {
( ) cvs
show
} def % строка первоначально содержит 3 пробела
Оператор string создает строку длиной n. Определение строковой переменной выглядит так:
/nstr 7 string def
где 7 -- длина строки (знаков). Рекурсивный вызов процедур даёт возможность рисовать фрактальные картинки, но это мы попробуем сделать на следующем занятии, когда изучим конструкции циклов. 16.11.2001 |