20. PS (ПОСТСКРИПТ) ГРАФИКА

Научная графика в языке ACL имеет дополнительные возможности по сравнению с языком Java и другими языками программирования. Дело в том, что при подготовке рукописей для публикации научных работ, большое распространение получило программирование рукописи на языке LaTeX с использованием векторных рисунков, программируемых на языке PS (постскрипт). Особенно широко это распространено среди пользователей компьютера с операционной системе UNIX. Но и в среде Windows также можно создавать и использовать постскрипт рисунки. Для этого надо иметь постскрипт интерпретатор Ghostview, который можно скачать здесь . Этот интерпретатор позволяет показывать рисунки на экране и печатать на принтере.

Код рисунка на языке постскрипт можно просто набрать любым текстовым редактором, если знать этот язык программирования. Сложность, однако, в том, что это язык низкого уровня, в котором есть только элементарные команды. И для создания сложного рисунка необходимо набирать сотни, а то и тысячи однотипных команд. По этой причине существуют автоматические постскрипт-генераторы, то есть программы, которые сами записывают постскрипт код в файл. В языке ACL таким постскрипт-генератором является команда #psgraph или короче #ps. Она генерирует постскрипт файл в несколько операций, причем число возможных операций опять же неограниченно и определяется только способностями автора языка. На данный момент существует несколько операций, описанных в этом разделе.

Итак, #ps -- это достаточно сложная команда позволяющая программисту приготовить график или картинку в виде постскрипт кода и записать его в файл типа encapsulated postscript (eps). График может состоять из некоторых готовых графических фрагментов, постскрипт код которых последовательно записывается в файл. Интерпретатор ACL способен только записать такой файл, но не может показать картинку. Последнее может быть сделано с помощью программы Ghostview или при печати файла на постскрипт принтере. Есть также другие программы, например, Ворд из МС Офис, которые показывают eps файлы в ограниченном режиме, то есть не все. Такая графика полезна как раз по причине высокого качества напечатанного на принтере рисунка. Постскрипт графика широко используется в публикациях из-за легкой переносимости без потери точности. Причина состоит в том, что эта графика является векторной в отличие от растровой графики.

Структура параметров данной команды является промежуточной между командами #w, #g и #eg. Ниже описаны общие идеи как использовать эту команду со ссылками на статьи #w, #g, и #eg, когда необходимо. В названии операций достаточно набрать два символа. С учетом сказанного выше ясно, что целью команды является создание полностью законченного eps-файла для печати на постскрипт принтере, просмотра программой Ghostview и использования в статьях, форматируемых на языке Латех. Эта цель достигается с использованием нескольких операций. На первом шаге eps-файл должен быть открыт для графики. Это делается следующей операцией

.

 #ps [op=of; twi=; the=; form=;]

Эта операция открывает eps-файл, имя которого (без расширения) определяется параметром [form]. Расширение всегда равно (.eps). Параметры [twi] и [the] определяют полный размер картинки в pt (points). Например, A4 бумага имеет размер 596*843 в единицах pt. Эта команда записывает заголовок eps-файла, который содержит Prolog. Prolog определяет некоторые новые постскрипт команды дополнительно к стандартным командам, которые используются в других готовых фрагментах, а также могут быть использованы непосредственно. Prolog может быть прочитан непосредственно в любом eps-файле, создаваемом этой командой. Эта операция должна предшествовать всем другим операциям. Здесь есть одна тонкость, состоящая в том, что вся графика, описанная ниже, использует в основном координаты точек как целые числа. Но данная операция задает не растр полной картинки а размер для печати в pt. Поэтому здесь нельзя задавать произвольно большие числа для координат. А что касается последующих фрагментов, то их можно описывать на сетке из большего числа точек и масштабировать на заданный размер.

Другие операции записывают код некоторых частных фрагментов картинки, которые могут быть использованы в комбинации друг с другом или повторены много раз. Первая операция позволяет включить в постскрипт файл непосредственно постскрипт код, который может быть взят из другого файла или из текстового массива t(). Это полезно, например, для включения растровой графики (см. команду #f [op=tops;]) или некоторых комментариев. Это делается операцией.

.

 #ps [op=ps; trx=; try=; sca=; file=; b=; le=;]

Обычно данные берутся из файла, чье имя определяется параметром [file]. Однако, если [file=here;], то данные будут взяты из массива t() начиная с элемента, определяемого [b] и точно [le] символов. Естественно текстовый массив t() должен быть предварительно записан. Кроме того, картинка, записанная как ps-код, будет при рисовании перемещена согласно значениям параметров [trx] и [try] и затем промасштабирована согласно значению [sca] с сохранением аспектного отношения. Это означает то, что к координатам всех точек будут сначала прибавлены координаты сдвига и затем они будут умножены на множитель масштаба. Так как параметры -- это целые числа, то нужно помнить, что реальные координаты сдвига получаются после умножения [trx] и [try] на 0.1, а масштабный множитель получается из [sca] после умножения на 0.01. Это относится и ко всем последующим операциям. Например, эта операция позволяет поместить заголовок с помощью следующего постскрипт кода
[X] [Y] m [R] r (... text ...)L -[R] r
где [] означают числа; буква L указывает напечатать текст латинскими буквами, но можно использовать и греческие буквы, если заменить L на G; буква m устанавливает координаты текста; буква r указывает, что текст нужно повернуть на указанный угол в градусах. Русские тексты могут быть напечатаны с использованием моего собственного фонта, но это более сложная процедура.

Из готовой графики на данный момент разработаны операции [plain figure] и [axonometry], которые делают те же графики, что и команды #w [op=pf;] и #g [op=axon;], но в ps-форме. Первая операция выглядит так.

.

 #ps [op=pf; trx=; try=; sca=; file=; b=; le=; mo=; wid=; hei=; xsh=; ysh=; sty=;
          bot=; top=; tsi=; col=; msi=; mki=; uni=; nx=;] X1 X2

Здесь [trx], [try] и [sca] имеют тот же смысл, что и выше. Параметр [file] определяет имя файла с численными данными для зависимостей. Если [file=here;], данные берутся из реального массива r() с учетом параметров [b] и [le], как обычно. Как и в команде #w данные должны быть записаны в компьютерном формате и [mo] задает модификации. Однако, в отличие от #w, здесь может быть нарисована только одна функция за одну операцию. Так что, если [mo=0;], только значения функции будут в файле. Число точек задается параметром [nx], который должен быть равен [le], если данные находятся в реальном массиве r(). Первый и последний значения аргумента должны быть заданы как аргументы X1 X2 . Если [mo=1;], данные представляют собой сначала [nx] аргументов и затем [nx] значений функции. Параметры [wid], [hei], [xsh], [ysh], [sty], [bot], [top], [tsi], [uni] те же самые, что и в команде #w [op=pf;].

Оси рисуются черными, но функция может быть цветной согласно [col]. Наконец [mki] может быть 0,1,2,3,4. Если [mki=0;], функция рисуется сплошной линией. В этом случае [msi] определяет толщину линии в единицах 0.01 pt (будьте осторожны!). В остальных случаях функция рисуется маркерами. Если [mki=1;], маркер есть белый сплошной прямоугольник, если [mki=2;], он есть цветной сплошной прямоугольник, если [mki=3;], он есть белый круг, и если [mki=4;], он есть цветной круг. Сами оси рисуются линиями с толщиной 0.5*[siz] pt без учета масштабирования. Задание масштабирования влияет также и на толщину всех линий. Таким образом параметром [siz] можно регулировать толщину линий. В отличие от #w эта операция может быть повторена много раз с различными функциями, разными цветами и маркерами, разными или теми же самыми осями или совсем без осей (то есть положение функций задается параметрами осей но оси могут отсутствовать). Так что по сравнению с командой #w, эта операция имеет больше возможностей. Вторая операция выглядит так

.

 #ps [op=ax; trx=; try=; sca=; col=; n=; c=; b=; wid=; hei=; tsi=;]

Эта операция позволяет программисту нарисовать аксонометрическую проекцию поверхности некоторого трехмерного объекта, описываемого однозначной функцией z(x,y) где x, y, z есть трехмерные координаты. Объект рисуется линиями через x-z и y-z сечения одновременно или раздельно. Невидимые линии не показываются. Объект помещается в координатные оси, которые показывают значения x, y и z координат. Аксонометрическая проекция делается используя точку зрения как направление между (0,0,0) точкой объекта и точкой зрения и отдельно расстояние между этими точками. Алгоритм устранения невидимых линий предполагает положительные координаты направления точки зрения около [1,1,1]. Ниже шаг за шагом описываются все параметры графика. Цвет определяется [col].

Полные размеры картинки задаются параметрами [wid] и [hei]. Эти параметры указывают только на прямоугольник, в котором находятся все линии. Цифры на осях могут находиться за пределами этого прямоугольника. В отличие от команды #g здесь параметры [xsh], [ysh] не используются. Вместо них нужно непосредственно использовать [trx] и [try], которые задают сдвиг прямоугольника линий из левого нижнего угла полного графика. Они все должны быть больше нуля, иначе цифры на осях окажутся за пределами графика. Параметр [sca] имеет то же значение, что и выше. Фонт для цифр на осях фиксирован и только параметр [tsi] указывает его размер в единицах pt. Функция z(x,y) всегда задается в реальном массиве r() начиная с первого номера [b]. Другие реальные параметры должны быть указаны в массиве r() стартуя с элемента с номером [n]. Эти параметры имеют следующую структуру:
xmi, xma, xfm, xdm, ymi, yma, yfm, ydm, zmi, zma, zfm, zdm, vp1, vp2, vp3, vpm, hx, hy.
Здесь [xmi] и [xma] минимальные и максимальные значения на оси x; [xfm] значение для установки первой короткой риски; [xdm] значение для разности между короткими рисками. Параметры, у которых имена начинаются с y и z означают то же самое для y и z осей. Значения [vp1], [vp2], [vp3] описывают направление точки зрения для аксонометрической проекции. Три координаты используются для удобства. Реально вектор нормируется на единицу. Расстояние до точки зрения задается отдельно значением [vpm] которое является десятичным логарифмом для избежания ввода очень больших чисел. Будте осторожными и не вводите большие числа так как 3 означает 1000, 5 означает 100000 и так далее. Обычно [hx]=1 и [hy]=1. Эти параметры удобны, если вместо реального трехмерного объекта желательно рисовать некую зависимость f(a,b) где [f], [a] и [b] могут иметь произвольные значения. В этом случае для получения разумной формы необходимо вводить истинные значения и затем подбирать масштабирующие коэффициенты [hx] и [hy] для x и y осей таким образом, что [da]*[hx] и [db]*[hy] имели бы значения близкие к [df] где da = [a]max - [a]min и то же самое для [b] и [f]. Кроме того, задаются целые параметры как элементы целого массива i() начиная с индекса [cod]. Эти параметры имеют следующую структуру:
nx, ny, ngv, bot, top, nxfm, nxsm, nyfm, nysm, nzfm, nzsm, nax
Здесь [nx] число точек на оси x; [ny] то же самое для оси y. Массив значений функций содержит только значения без аргументов как матрица [nx][ny]. Параметр [ngv] должен быть равен 1 (для x-z сечений) 2 (для y-z сечений) 3 (для обоих сечений одновременно). Параметры [bot] и [top] описывают длину коротких и длинных рисок в единицах, которые равны 0.001 части диагонали для x и y осей соответственно спроектированных. Некоторая коррекция может быть сделана если [vp1] отличается от [vp2]. Параметр [nxfm] есть номер первой короткой риски, которая преобразуется в длинную риску и получает значение. Параметр [nxsm] есть число коротких рисок между длинными рисками. Другие параметры означают то же самое для y и z осей. Последний параметр [nax] описывает появление вертикальной осей. Если [nax] = 0, левая и правая вертикальные оси появятся вместе со средней осью и горизонтальными линиями уровней. Если [nax] = 1, только правая вертикальная ось появится около оси x. Если [nax] = 2, только левая вертикальная ось появится около оси y.
Наконец eps-файл должен быть закрыт. Это делается операцией

.

 #ps [op=cf;]

То есть эта операция очень простая, но она необходима. Вот пример готовой программы для рисования аксонометрической проекции гауссовой поверхности

 # y=-9; d=0.2; j=21;
 #rep 91  # x=-9;
  #rep 91  # r(j)=exp(-0.03*(x*x+y*y)); j=j+1; x=x+d; #end  # y=y+d;
 #end 
 #ps [op=of; twi=450; the=320; form=ax-exam;]
 #d 11 i(1) 91 91 3 10 20 2 3 2 3 1 1
 #d 18 r(1) -0,9 0,9 -0,9 0,1 -0,9 0,9 -0,9 0,1 0 1 0 0,1 1 1 0.5 3 1 1
 #p [tsi=14; col=247;] 
 #ps [op=ax; trx=75; try=50; sca=1; n=1; c=1; b=21; wid=300; hei=250;]
 #ps [op=cf;]

Для эффективного использования этой команды полезно знать основы языка постскрипт. Полное описание этого языка имеет огромные размеры, но иногда достаточно знать несколько простых команд и общие принципы. Можно почитать мою собственную книгу с примерами об этом языке тут . Также есть более старое описание моей другой программы VKPS, которое само написано на постскрипте с использованием этой программы и конвертировано в pdf. Описание тут .