Рисуем молекулы с помощью PostScript

от автора

Векторная графика очень удобна для иллюстраций. Молекулы состоят из атомов соединённых связями. Хочется, чтобы операции редактирования рисунка химической структуры осуществлялись согласно физическому устройству молекул: выделил атом, перенес его, повернул фрагмент молекулы, подписал… Практически все визуализаторы атомных структур экспортируют вид в растр, что усложняет подготовку иллюстраций. В этой заметке я расскажу о способе отрисовки 3D структур в векторном формате, а также о том, как в этом поможет язык PostScript.

Вместо красивой растровой картинки (слева) получим винтажную иллюстрацию (справа).
Вместо красивой растровой картинки (слева) получим винтажную иллюстрацию (справа).

Достаточно много программ умеют экспортировать структуру в векторную графику: SVG, PDF, EPS. Однако, часто это сделано лишь формально — полученные изображения состоят из множества примитивов, разобрать их по атомам и связям практически невозможно. Размер такого векторного файла тоже большой, словом, беда. Из множества молекулярных конструкторов лишь два удовлетворяют по качеству кода векторной картинки: GaussView и Molden. Последняя программа доступна всем желающим, так что примеры построены с её помощью, тем не менее, все приведенные ниже рецепты применимы (с некоторыми модификациями) и к векторным иллюстрациям сделанными программой GaussView. Итак, Molden!

Molden
Molden

Открываем файл со структурой, сохраняем в PostScript.

PostScript

В файле видим человеческий текст:

%!PS-Adobe-2.0 EPSF-2.0 %%Title: Molden %%For: Schaft %%Creator: Drs G Schaftenaar %%DocumentFonts: Courier %%Pages (atend) %%BoundingBox: 0 0 612 792 %%EndComments % %###### User Preferences ############ % %---- SIZE AND ORIENTATION OF THE PLOT --- % /size    {  0.24 } def %---- These number can be negative ------- /originx {  39.0 } def /originy { 753.0 } def /angle   { -90.0 } def %For Portrait use %/originx { 40.0 } def %/originy { 240.0 } def %/angle   { 0.0 } def %and BoundingBox: 25 255 535 765

За отрисовку сфер-атомов отвечает процедура \doatom, за стержни — \dorod. Сначала отключим вывод логотипа Molden.

%---- Include Tabel & Logo, Fontsize ----- /tabel {true} def /titleandlogo {true} def % ставим здесь false!

Без дальнейших модификаций рисунок будет таким, 4082 графических примитива. Несколько неудобно.

4082 примитива
4082 примитива

Число примитивов можно значительно сократить небольшой правкой.

%---- SET BOND RENDERING:  --------------- %---- shadedrod, whiterod, blackrod  ----- % /doatom { dosketchysmoothatom } def  /dorod  { sketchyshadedrod }    def % % облегченные версии (меньше примитивов) /dosketchysmoothatom  % вместо прежнего doatom { gsave   rx ry translate   90 -15 1 % вместо прежнего цикла 90 1 1 - это единственное изменение   { gsave     dup cos hue exch satu exch sethsbcolor sin dup scale     newpath     0 0 rad 0 360 arc     closepath fill grestore } for     grestore } def /sketchyshadedrod { gsave   x1 y1 translate   x2 x1 neg add   y2 y1 neg add   {atan neg rotate} stopped not {   85 -15 0 % вместо 87 -3 0 - это единственное изменение   {dup   gsave   newpath    cos 1.0 cosb 0.5 mul neg add mul    hue exch satu exch sethsbcolor    sin 1.0 scale    1 cosb scale    0 0 hd 0 180 arcn    x2 x1 neg add dup mul    y2 y1 neg add dup mul    add sqrt   0 cosb eq {/cosb 1.0 def} if 0 exch cosb div translate    0 0 hd 180 360 arc   closepath fill   grestore } for   } if   grestore } def
Здесь уже 410 примитивов вместо 4082.
Здесь уже 410 примитивов вместо 4082.

Пойдем дальше и напишем на сей раз свои собственные процедуры!

/doatom { docirclecoloratom } def /dorod { dostick } def  % ширина связи, цвет её линии, толщина штриха /stickwidth {16} def /stickgreycolor  {0} def /strokelinewidth {4} def  /docirclecoloratom { gsave     strokelinewidth setlinewidth     rx ry translate     newpath 0 0 rad 0 360 arc closepath     gsave     hue satu 1.0 sethsbcolor fill     grestore     stroke     0 0 rad 0.75 mul -60 0 arc     stroke     grestore } def % процедура dostick уже создана Molden

Этот код произведет такую картинку:

Это очень простой рисунок, легковесный. Каждый атом — 3 примитива. Окружность, окрашенный круг, дуга. Связь — одна линия. Легко разобрать на запчасти и сделать всё что угодно.

/docircleatom { gsave     strokelinewidth setlinewidth     rx ry translate     newpath 0 0 rad 0 360 arc closepath     gsave     1 setgray fill     grestore     stroke     gsave     1.00 0.55 scale     0 0 rad 0 180 arc     stroke     grestore     0.55 1.00 scale     0 0 rad -90 90 arcn     stroke     grestore } def

Этот код радикально сведет рисунок к черному и белому. Как в старых книгах.

Я добавил подпись - длину водородной связи.
Я добавил подпись — длину водородной связи.

Заключение

PostScript удивительно хорош в создании иллюстраций. Он лёгок в освоении. В этой заметке я привёл способ как сделать простые, но подчас очень и очень нужные вещи при подготовке публикации или постера на конференцию. Однако, можно пойти дальше! Очень рекомендую книгу Mathematical Illustrations.

ссылка на оригинал статьи https://habr.com/ru/post/553056/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *