Как стать автором
Обновить

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

Время на прочтение3 мин
Количество просмотров3.5K

Векторная графика очень удобна для иллюстраций. Молекулы состоят из атомов соединённых связями. Хочется, чтобы операции редактирования рисунка химической структуры осуществлялись согласно физическому устройству молекул: выделил атом, перенес его, повернул фрагмент молекулы, подписал… Практически все визуализаторы атомных структур экспортируют вид в растр, что усложняет подготовку иллюстраций. В этой заметке я расскажу о способе отрисовки 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.

Теги:
Хабы:
Всего голосов 23: ↑23 и ↓0+23
Комментарии4

Публикации

Истории

Ближайшие события

22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
2 – 18 декабря
Yandex DataLens Festival 2024
МоскваОнлайн
11 – 13 декабря
Международная конференция по AI/ML «AI Journey»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань