2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 О рисовании EPS-картинок. Точнее, о программировании на PS.
Сообщение16.12.2007, 17:34 


29/09/06
4552
Алексей К. в ответ на это сообщение от Егора писал(а):
Думаю иногда --- чем бы сам мог поделиться? Наверное, выдать несколько уроков по PostScript, рассказать, как это забавно и полезно. Язык как будто задуман для геометров. Или, может, я потому увлёкся 2D-дифф.геометрией, что он мне понравился, все гипотезы на PostScript-е проверяю, и EPS-картинки ручками рисую (а в 3D по своей воле не хожу, только когда начальники или PSP вынуждают)?

Продолжение надо, впрочем, выносить в отдельную тему...


Сейчас, конечно, куча всякого рода математических пакетов дают возможнось любую картинку заполучить; когда я обратил взор на PostScript, такой халявы не было. Не знаю, стоит ли рассказать о нём математикам, не чуждым программированию... Ибо сам я как раз не знаком с альтернативным вариантом. Знаю лишь, что коллеги часто прибегают с просьбой подредактировать PS-катринку --- буковку передвинуть, цвет/текст поменять, отклиповать, итп.

К примеру --- если кому известен мой сюжет Дифф. уравнение в картинках, --- этот простой диффур. решался непосредственно "в принтере", по результаам строились графики. Однажды я превратил PS-принтер в Фурье-спектрометр: на вход подавались измерения солнечной активности за 40 лет, на выходе были спектры...

Если у некоторой, не очень маленькой, части форумчан возникнет желание познакомиться с этим делом поближе --- я смогу, наверное, сделать несколько... презентаций (до сих пор избегал и этого слова, и этого действа). Смогу ли их сделать в роскошном стиле, продемонстрированном Егором --- пока не уверен.

Вот маленькая программка-примерчик. Скопируйте код в Archimed.PS

Код:
%!
%       Draw Archimedian spiral (polar angle from 0 to 3600 deg)
%
300 350 translate .75 dup scale
-250 0 moveto 250 0 lineto 0 -250 moveto 0 250 lineto stroke
2 setlinewidth 1 0 0 setrgbcolor 0 0 moveto
0 3 3600 {%   start "for" loop
  dup 10 div exch 2 copy cos mul 3 1 roll sin mul lineto
} for stroke
showpage


Добавлена 1 строка --- некоторая разноцветица получилась:

Код:
%!
%       Draw Archimedian spiral (polar angle from 0 to 3600 deg)
%
300 350 translate .75 dup scale
-250 0 moveto 250 0 lineto 0 -250 moveto 0 250 lineto stroke
2 setlinewidth 1 0 0 setrgbcolor 0 0 moveto
0 3 3600 {%   start "for" loop
  dup 90 mod 3 eq {currentpoint stroke moveto currentrgbcolor 3 1 roll setrgbcolor} if
  dup 10 div exch 2 copy cos mul 3 1 roll sin mul lineto
} for stroke
showpage


Вот небольшая программка, рисующая кривую по её натуральному уравнению (рисуется 3 страницы). (Будучи написанной когда я только начал изучать PS, т.е. лет 20 назад, она НЕ может служить примером хорошего стиля программирования).
код: (chezaro.ps) [ скачать ] [ спрятать ]
  1. %!PS 
  2. % ----------------------------------------------------- proc Nat_curve, definition 
  3. /Nat_curve {% {k(s)} S tau0 x0 y0 Nat_curve 
  4. 16 dict begin 
  5. /Nd 10 def % Nd = 10  
  6. /h currentlinewidth 4 div def % h = currentlinewidth/4  
  7. /ds h 3 mul def % ds = 3h  
  8. /rad 57.295779513 def 
  9. /maxabs {abs exch abs 2 copy lt {exch} if pop} bind def % maxabs(x,y) = max(abs(x),abs(y)) 
  10. gsave translate rotate newpath 0 0 moveto 
  11. /s2 exch def /Ks exch def [/s /x /y /t] {0. def} forall 
  12. { /kmax s Ks s ds add Ks maxabs def /dds 8 h mul kmax div sqrt def  
  13. dds ds gt {/ds dds ds div 2 gt {ds 2 mul} {dds} ifelse def} 
  14. {/ds dds def} ifelse 
  15. /ss s ds add def ss s2 gt {/ds s2 s sub def /ss s2 def} if 
  16. /dds ds Nd div def 
  17. Nd {/t t s Ks dds mul rad mul add def 
  18. /x x t cos dds mul add def 
  19. /y y t sin dds mul add def /s s dds add def  
  20. } repeat 
  21. x y lineto /s ss def 
  22. currentpoint stroke currentrgbcolor 3 1 roll setrgbcolor moveto 
  23. s s2 ge {exit} if kmax h mul 1 gt {exit} if 
  24. } loop 
  25. grestore end} def 
  26. % -------------------------------------------------------------- end of definition 
  27. /TimesRoman findfont 30 scalefont setfont 
  28. % ------------------------------------------------------------------- 1-st Page 
  29. gsave 
  30. 0.75 dup scale 
  31. 200 930 moveto (k\(s\) = A sin\(B s\) + const ) show 
  32.  
  33. 1.5 setlinewidth 1 0 0 setrgbcolor 
  34. {sin 0.3 add 50 div} bind 8100 0 500 180 Nat_curve % k(s) = [sin(s)+0.3]/50, s=[0;8100] 
  35. % tau0=0, x0=500, y0=800 
  36. {sin 0.75 add 50 div} bind 8000 0 500 800 Nat_curve  
  37. {sin 0.5 add 50 div} bind 7380 0 460 670 Nat_curve 
  38. grestore 
  39. showpage 
  40. % --------------------------------------------------------------------- 2-nd Page 
  41. gsave 
  42. 100 600 moveto (Cornu spiral: k\(s\) = A s ) show 
  43. 1.5 setlinewidth 1 0 0 setrgbcolor 
  44. {30000 div} bind 2000 90 250 300 Nat_curve 
  45. {30000 div} bind 2000 -90 250 300 Nat_curve 
  46. grestore 
  47. showpage 
  48. % -------------------------------------------------------------------- 3-rd Page 
  49. gsave 
  50. 100 600 moveto ( k\(s\) = 1/R = Const \(Smax=100 circles\)) show 
  51. 1.5 setlinewidth 1 0 0 setrgbcolor 
  52. { pop 0.005 } 6.28 200 mul 100 mul 0 270 100 Nat_curve 
  53. grestore 
  54. showpage 
  55. % -------------------------------------------------------------------- EOF 

 Профиль  
                  
 
 
Сообщение17.12.2007, 12:48 
Заслуженный участник
Аватара пользователя


18/05/06
13440
с Территории
Цитата:
Раз пошла такая пьянка - режь последний огурец.
А вот мои пять копеек (не помню, может, уже постил здесь, но скорее всё-таки нет):
Код:
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 12 272 508 608
%%Creator: ISN
%!
/a{bind def}bind def
/b{moveto lineto}a
/c{index}a
/d{3 c 2 c}a
/e{d sub dup mul d sub dup mul add 2 gt
{d sub 2 div d add 2 div add d sub 2 div 0 exch sub
5 c 4 c add 2 div add exch 1 c 1 c 6 2 roll e e}{b} ifelse}a
newpath
120 500 440 500 e
stroke
showpage

(Пример сознательно запутан для краткости и трудности чтения)

 Профиль  
                  
 
 
Сообщение17.12.2007, 13:15 


29/09/06
4552
ИСН писал(а):
А вот мои пять копеек...

Я бы и 5 рублей дал за это...

 Профиль  
                  
 
 Спасибо!
Сообщение18.12.2007, 00:58 


22/06/05
164
Алексей К., за интересную тему и примеры спасибо! На ПостСкрипте программы читая, Йоды-магистра речи стиль понимать начинаю. :) ИСНом сотворённого дракона постичь дабы, не жалко январь 2008 потратить!

Нашёл и немедленно скачал "Tuturial and Cookbook" и "Thinking in PostScript". Какие ещё учебники посоветуете (желательно, конечно, доступные для скачивания)?

 Профиль  
                  
 
 Re: Спасибо!
Сообщение18.12.2007, 10:39 


29/09/06
4552
Егор писал(а):
Какие ещё учебники посоветуете (желательно, конечно, доступные для скачивания)?

Именно эти. Не помешает и PostScript Language Reference Manual, где, в частности, удобный свод всех комманд языка (гл. 8.1).

Добавлено спустя 5 минут 35 секунд:

Егор писал(а):
ИСНом сотворённого дракона постичь дабы, не жалко январь 2008 потратить!

Может, он сам (ИСН) расколется, а нет --- постигнем в январе. Сейчас у меня на носу каникулы, и, видимо, безынтернетные...
Надеюсь, моя спиралька понятна на 100%...

 Профиль  
                  
 
 
Сообщение18.12.2007, 12:07 
Заслуженный участник
Аватара пользователя


18/05/06
13440
с Территории
А что тут раскалываться: берёшь Reference manual и читаешь.
Примерный смысл:
Код:
Назовём слово "назовём" - "Ы".
Ы слово "слово" - "У".
Ы У "линия"...

Восхитительный язык, что и говорить.

 Профиль  
                  
 
 Re: Спасибо!
Сообщение18.12.2007, 14:29 


29/09/06
4552
Егор писал(а):
речи стиль понимать начинаю. :)

Этот Ваш абарот напомнил мне пассаж из одной книжицы (американской), цель которого была объяснить европейцам, что выучить японский европейцу не так уж сложно. Надо только перейти от Фортрановского/Си-шного мышления к стековому, т.е вместо
$$\mbox{ \tt moveto(x,y)}$$
говорить на PostScripte (какой-то другой стековый язык был упомянут, предшественник PS)
$$\mbox{ \tt  x y moveto}$$
Японцы действительно так строят фразу --- выкладывают слова на стек, потом чего-то с этим делают:
Я в лингво-форуме приводил такой пример:
"Люблю гулять под дождём" --- "Ame-no naka de aruku koto-ga suki desu".
аme --- дождь;
ame-no ---- притяжательный падеж (rain's)
ame-no naka --- rain's interior, внутренность дождя;
ame-no naka de --- by (means of) внутренность дождя;
ame-no naka de aruku --- гулять посредством внутренности дождя;
ame-no naka de aruku koto-ga --- субстантивируем это действо, т.е. делаем из него некое существительное, которое можно будет, например, любить;
ame-no naka de aruku koto-ga suki desu --- наконец, любим...
(Гуляют они внутри дождя, а не под дождём)

Добавлено спустя 1 час 30 минут 36 секунд:

Всё же сделаю это сейчас, в декабре :P
ИСН, выложив сей чудный примерчик, надо полагать, не возражает против его раскурочивания. Для начинающих многое прояснится.

Сначала одно упрощение --- оставляем одну функцию e:

Код:
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 12 272 508 608
%%Creator: ISN
/e {%
  3 index 2 index sub dup mul 3 index 2 index sub dup mul add 2 gt
  {3 index 2 index sub 2 div 3 index 2 index add 2 div add
   3 index 2 index sub 2 div 0 exch sub
   5 index 4 index add 2 div add exch 1 index 1 index 6 2 roll e e
  }{moveto lineto} ifelse
} bind def
newpath
120 500 440 500 e
stroke
showpage


Теперь такое преобразование --- две "неявные функции" делаем явными прцедурами e1 и e2:

Код:
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 12 272 508 608
%%Creator: ISN

/e {%
  3 index 2 index sub dup mul 3 index 2 index sub dup mul add 2 gt
  {e1}{e2} ifelse
} bind def

/e1 {%
   3 index 2 index sub 2 div 3 index 2 index add 2 div add
   3 index 2 index sub 2 div 0 exch sub
   5 index 4 index add 2 div add exch 1 index 1 index 6 2 roll e e
} bind def

/e2 {moveto lineto} bind def

newpath
120 500 440 500 e
stroke
showpage


Теперь --- подробное расписывание:

Код:
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 12 272 508 608
%%Creator: ISN
%!

/e {%       на стеке предполагается наличие 4-х аргументов
                                   % x1 y1 x2 y2
                                   % (3)(2)(1)(0)     
3 index                            % x1 y1 x2 y2 x1     %вытащили 3-й с конца арг:
2 index                            % x1 y1 x2 y2 x1 x2
sub                                % x1 y1 x2 y2 x1-x2
dup   %(duplicate)                 % x1 y1 x2 y2 x1-x2 x1-x2
mul                                % x1 y1 x2 y2 (x1-x2)^2
3 index 2 index                    % x1 y1 x2 y2 (x1-x2)^2 y1 y2
sub dup mul                        % x1 y1 x2 y2 (x1-x2)^2 (y1-y2)^2
add                                % x1 y1 x2 y2 (x1-x2)^2+(y1-y2)^2
2 gt                              % x1 y1 x2 y2 bool(true/false) [ (x1-x2)^2+(y1-y2)^2 > 2 ]
          % далее на стек кладутся 2 процедурки, ибо когда появится оператор
          % ifelse, он потребует 3-х аргументов:
          %   bool {proc1_for_true} {proc2_for_false} ifelse   
       {e1}                     % x1 y1 x2 y2 bool {e1}
       {e2}                     % x1 y1 x2 y2 bool {e1} {e2}
       ifelse                   % x1 y1 x2 y2  (выполнившись, ifelse съел 3 последних арг. со стека)
} bind def


/e1 {%       на стеке предполагается наличие 4-х аргументов
                                  % x1 y1 x2 y2 
  3 index 2 index sub             % x1 y1 x2 y2 (x1-x2)
  2                               % x1 y1 x2 y2 (x1-x2)   2
  div                             % x1 y1 x2 y2 (x1-x2)/2
  3 index 2 index                 % x1 y1 x2 y2 (x1-x2)/2 y1 y2
  add 2 div                       % x1 y1 x2 y2 (x1-x2)/2 (y1+y2)/2
  add                             % x1 y1 x2 y2 [(x1-x2)/2+(y1+y2)/2]
%далее посл. арг. обозначен как s1: x1 y1 x2 y2 s1
  3 index 2 index sub 2 div       % x1 y1 x2 y2 s1 (y1-y2)/2
  0                               % x1 y1 x2 y2 s1 (y1-y2)/2 0
  exch                            % x1 y1 x2 y2 s1 0 (y1-y2)/2
  sub                             % x1 y1 x2 y2 s1 0-(y1-y2)/2 [ = (y2-y1)/2 ]
      %     последовательность            0 exch sub
      %     можно было заменить командой  neg   (negate)
  5 index 4 index                 % x1 y1 x2 y2 s1 (y2-y1)/2 x1 x2
  add 2 div add                   % x1 y1 x2 y2 s1 (y2-y1)/2+(x1+x2)/2   [ = s2 ]
  exch                            % x1 y1 x2 y2 s2 s1
  1 index 1 index                 % x1 y1 x2 y2 s2 s1 s2 s1
  6 2                             % x1 y1 x2 y2 s2 s1 s2 s1 6 2
%6 2 roll  --- циклич. сдвиг группы из 6 последних аргументов 2 раза
  roll                            % x1 y1  s2 s1 x2 y2 s2 s1
  e    % рекурсия: выполнить процедуру e для x2 y2 s2 s1, новое содержимое стека неизвестно ---
       %                               или их съели, или нафракталили новые четвёрки...             
  e
} bind def

/e2 {%       на стеке предполагается наличие 4-х аргументов
               % x1 y1 x2 y2                       
  moveto       % x1 y1
  lineto       %          (стек опустел)
} bind def

newpath
120 500 440 500 e
stroke
showpage

 Профиль  
                  
 
 
Сообщение18.12.2007, 20:13 
Заслуженный участник
Аватара пользователя


18/05/06
13440
с Территории
:shock: :shock:
раньше я думал, что видел дотошных людей.
Теперь понимаю: нет, не видел!
Но увидел сейчас.

Атец!

 Профиль  
                  
 
 
Сообщение18.12.2007, 20:36 


29/09/06
4552
Знали бы Вы, как омерзительна работа, вместо делания которой я, пока никто не видел, написал это. Зато теперь Егору, например, совсем всё понятно... Ну и Вы оператор neg узнали (бы)...

 Профиль  
                  
 
 
Сообщение08.01.2008, 13:49 


22/06/05
164
Спасибо за объяснения! Спираль Архимеда понятна, кривая дракона теперь тоже (в общих чертах).
Для тренировки написал на операции с комплексными числами (сложение, вычитание и умножение). Буду рад советам и замечаниям, в том числе по стилю и оформлению. Как лучше определять операции --- чтобы они пожирали свои аргументы или нет?
Код:
%!PS-Adobe-2.0
% Complex arithmetic: add, sub, mul
/cadd { % x1 y1 x2 y2 -> x1+x2 y1+y2
  exch     % x1 y1 y2 x2
  4 3 roll % y1 y2 x2 x1
  add      % y1 y2 x1+x2
  3 1 roll % x1+x2 y1 y2
  add      % x1+x2 y1+y2
} def

/csub { % x1 y1 x2 y2 -> x1-x2 y1-y2
  exch 4 3 roll exch sub 3 1 roll sub
} def

/cmulre { % x1 y1 x2 y2 -> x1*x2-y1*y2
  exch     % x1 y1 y2 x2
  4 3 roll % y1 y2 x2 x1
  mul      % y1 y2 x1*x2
  3 1 roll % x1*x2 y1 y2
  mul sub  % x1*x2+y1*y2
} def

/cmulim { % x1 y1 x2 y2 -> x1*y2+x2*y1
  4 3 roll mul 3 1 roll mul add
} def

/cmul { % x1 y1 x2 y2 -> x1*x2-y1*y2 x1*y2+x2*y1
  4 copy cmulre 5 1 roll cmulim
} def

% show numbers and complex numbers:
/numbershow { % x -> (show)
  10 string cvs show
} def

/complexshow { % x y -> (show)
  exch numbershow
  dup 0 ge { (+) show } if
  numbershow (i) show
} def

% main (testing):
/z1 { 50 2 } def
/z2 { 3 10 } def
/Courier findfont 14 scalefont setfont
72 740 moveto (z1 = ) show z1 complexshow
72 720 moveto (z2 = ) show z2 complexshow
72 680 moveto (z1+z2 = ) show z1 z2 cadd complexshow
72 660 moveto (z1-z2 = ) show z1 z2 csub complexshow
72 640 moveto (z1*z2 = ) show z1 z2 cmul complexshow
showpage

 Профиль  
                  
 
 
Сообщение08.01.2008, 14:04 


29/09/06
4552
Подумаю и отвечу позже. Пока лишь впарю сюда варианты из моей библиотечки. Дабы сравнивать за обедом по бумажке напечататанной. Относительно простые вещи я не комментирую столь подробно. Аккуратностию тоже не оличаюсь...
Код:
/XYadd {% x1 y1 x2 y2  --> x1+x2 y1+y2
  3 -1 roll add 3 1 roll add exch
} bind def

/XYsub {% x1 y1 x2 y2  --> x1-x2 y1-y2
  3 -1 roll sub neg 3 1 roll sub exch
} bind def

/XYmul {% x1 y1 x2 y2  --> (x1+I*y1)*(x2+I*y2)
   4 copy   3 -1 roll mul neg 3 1 roll mul add
   5 1 roll 4 -1 roll mul     3 1 roll mul add
} bind def

/XYdiv {% x1 y1 x2 y2  --> (x1+I*y1)/(x2+I*y2)
   2 copy dup mul exch dup mul add 5 1 roll neg XYmul
   2 index div 3 1 roll exch div exch
} bind def

 Профиль  
                  
 
 
Сообщение09.01.2008, 12:12 


29/09/06
4552
Егор писал(а):
Буду рад советам и замечаниям, в том числе по стилю и оформлению. Как лучше определять операции --- чтобы они пожирали свои аргументы или нет?

Стиль Вы черпаете из тех же книжек, что и я когда-то.
И, как человек программирующий, сами сделаете выводы из сравнения моего и своего кода. Что лучше --- "6 -2 roll" или "6 4 roll", наверное, не столь важно и не стоит думать. Когда-то, когда оптимизировали каждую буковку, вопрос был актуальнее. Наверное, "6 -2" предпочтительнее и читабельнее.
Не вижу особой нужды в отдельных функциях для действительной и мнимой части при умножении. Я бы предпочёл одну функцию вместо трёх, и в тех редких случаях, когда нужна одна из частей, ненужную бы pop-нул (вычислил и выкинул).

Математические операции должны пожирать аргументы. "Должны" в смысле так разумнее, так сделано и в языке. Кому надо --- спасёт с помощью 4 copy cmul, например.
Пример оператора, оставляющего аргумент на стеке --- aload. Предполагается видимо, что человек захочет после этого длину массива спросить.

Каку-нибудь более интересную задачку, которая появится у Вас, обсудить будет интереснее. Могут появиться решения/конструкции, которые "обычному прграммисту" в голову не прийдут.

 Профиль  
                  
 
 
Сообщение10.01.2008, 12:06 


29/09/06
4552
Вот ещё источник учебной информации Acumen journal (см., наверное, ранние выпуски).

 Профиль  
                  
 
 
Сообщение15.01.2008, 00:57 
Заслуженный участник


18/03/07
1068
Господа, можно глупый вопрос?
Нет ли у вас на примете какого-нибудь «конвертера», который позволил бы перекинуть известный рисунок tiger.ps (он поставляется, к примеру, с Ghostscript) во что-нибудь браузерное (SVG, VRML, <canvas>)?

 Профиль  
                  
 
 
Сообщение15.01.2008, 01:18 
Экс-модератор
Аватара пользователя


23/12/05
12068
в SVG из ps можно в CorelDraw перегнать. Насчет остальных форматов я не знаю

Добавлено спустя 3 минуты 4 секунды:

luitzen писал(а):
tiger.ps

Sorry, а в чем проблема именно с этим тигером?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: Lenchik


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group