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
13438
с Территории
Цитата:
Раз пошла такая пьянка - режь последний огурец.
А вот мои пять копеек (не помню, может, уже постил здесь, но скорее всё-таки нет):
Код:
%!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
13438
с Территории
А что тут раскалываться: берёшь 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
13438
с Территории
: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
12063
в SVG из ps можно в CorelDraw перегнать. Насчет остальных форматов я не знаю

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

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

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

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

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



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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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