Новости

О проекте

Зачем?

Используемое ПО

Методика разработки сцен на PostScript

Операторы языка PostScript

Библиотека

Изучение языка

Урок 1

Урок 2

Урок 3

Урок 4

Урок 5

Урок 6

Урок 7

Статьи

Ссылки...

Занятие третье

Кривые

Для построения реального изображения одних отрезков прямых линий явно недостаточно. Поэтому в 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, напоминаю, операторы сравнения следуют за сравниваемыми величинами.
Оператор   Значение

eg

 

= (равно)

gt

 

> (больше)

ge

 

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

ne

 

<> (не равно)

lt

 

< (меньше)

le

 

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

Логические операторы: 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



©Фурашев А. 2002
e-mail

Хостинг от uCoz