Визуализация на грешка в OSX (?) при конвертиране на кривата на Безие в .eps файл в .pdf

Имам малък .eps файл, който използва криви на Безие с дебела ширина на линията, за да постигне определен ефект. Този файл се показва както очаквам в gv, но когато го конвертирам в .pdf (напр. с ps2pdf или като отворя файла с Preview на Mac, работещ с OSX), той изобразява някои от кривите неправилно (или поне не по начина, по който очаквах); в средата на кривата нормалите към кривата изглежда се обръщат, създавайки странен артефакт.

Ето въпросния .eps файл като код:

%!PS-Adobe-2.0 EPSF-2.0
%%BoundingBox: 0 0 750 200
gsave 50 50 scale 1 3 translate

/edge{4 dict begin
/y2 exch def
/x2 exch def
/y1 exch def
/x1 exch def
gsave
1 setgray
1 8 div setlinewidth
newpath
x1 y1 moveto x2 y2 lineto
stroke
0 setgray
1 20 div setlinewidth
newpath
x1 y1 moveto x2 y2 lineto
stroke
x1 y1 0.07 0 360 arc fill stroke
x2 y2 0.07 0 360 arc fill stroke
grestore
end}def

/cur_edge{7 dict begin
/T exch def
/angle2 exch def
/y2 exch def
/x2 exch def
/angle1 exch def
/y1 exch def
/x1 exch def
gsave
1 setgray
1 8 div setlinewidth
newpath
x1 y1 moveto 
x1 angle1 cos T mul add y1 angle1 sin T mul add
x2 angle2 cos T mul add y2 angle2 sin T mul add
x2 y2 curveto
stroke
0 setgray
1 20 div setlinewidth
newpath
x1 y1 moveto 
x1 angle1 cos T mul add y1 angle1 sin T mul add
x2 angle2 cos T mul add y2 angle2 sin T mul add
x2 y2 curveto
stroke
x1 y1 0.07 0 360 arc fill stroke
x2 y2 0.07 0 360 arc fill stroke
grestore
end}def

/fat_edge{7 dict begin
/T exch def
/angle2 exch def
/y2 exch def
/x2 exch def
/angle1 exch def
/y1 exch def
/x1 exch def
gsave
0 setgray
1 4 div setlinewidth
newpath
x1 y1 moveto 
x1 angle1 cos T mul add y1 angle1 sin T mul add
x2 angle2 cos T mul add y2 angle2 sin T mul add
x2 y2 curveto
stroke
0.9 setgray
1 5 div setlinewidth
newpath
x1 y1 moveto 
x1 angle1 cos T mul add y1 angle1 sin T mul add
x2 angle2 cos T mul add y2 angle2 sin T mul add
x2 y2 curveto
stroke
grestore
end}def

/fat_vertex{4 dict begin
/angle exch def
/y exch def
/x exch def
/T 0.14 def
gsave
0.9 setgray
1 5.5 div setlinewidth
newpath
x y moveto
x angle cos T mul add y angle sin T mul add lineto
stroke
grestore
end}def

/extra_fat_vertex{5 dict begin
/y exch def
/x exch def
/w 0.16 def
gsave
1 setgray
newpath
x w sub y w sub moveto
x w add y w sub lineto
x w add y w add lineto
x w sub y w add lineto
closepath
fill
stroke
0 setgray
/v 0.12 def
newpath
x v sub y v sub moveto
x v add y v sub lineto
x v add y v add lineto
x v sub y v add lineto
closepath
fill    
0.9 setgray
/u 0.095 def
newpath
x u sub y u sub moveto
x u add y u sub lineto
x u add y u add lineto
x u sub y u add lineto
closepath
fill    
grestore
end}def

/extra_fat_triangle{5 dict begin
/y exch def
/x exch def
/w 0.16 def
gsave
1 setgray
newpath
x w sub y w sub moveto
x w 1.1 mul add y lineto
x w sub y w add lineto
closepath
fill
stroke
0 setgray
/v 0.12 def
newpath
x v sub y v sub moveto
x v add y lineto
x v sub y v add lineto
closepath
fill    
0.9 setgray
/u 0.095 def
newpath
x u sub y u sub moveto
x u 0.85 mul add y lineto
x u sub y u add lineto
closepath
fill    
grestore
end}def

/extra_fat_triangle_left{5 dict begin
/y exch def
/x exch def
/w 0.16 def
gsave
1 setgray
newpath
x w add y w sub moveto
x w 1.1 mul sub y lineto
x w add y w add lineto
closepath
fill
stroke
0 setgray
/v 0.12 def
newpath
x v add y v sub moveto
x v sub y lineto
x v add y v add lineto
closepath
fill    
0.9 setgray
/u 0.095 def
newpath
x u add y u sub moveto
x u 0.85 mul sub y lineto
x u add y u add lineto
closepath
fill    
grestore
end}def

0 0 90 2 0 270 1 cur_edge
% 0 0 270 2 0 90 1 cur_edge
2 0 90 0 0 270  1 cur_edge
0 0 180 0.5 -2 180 1 cur_edge
0.5 -2 90 1.5 -1.3 180 0.5 cur_edge
1.5 -1.3 270 2.5 -2 270 0.7 cur_edge
2.5 -2 90 0.5 -2 270 1 cur_edge %
2.5 -2 0 3 -0.75 0 1 cur_edge
3 -0.75 270 1.5 -1.3 0 0.7 cur_edge
3 -0.75 180 1.5 -1.3 90 0.7 cur_edge
3 -0.75 90 2 0 0 0.5 cur_edge

5 0 translate
0 0 90 2 0 270 1 fat_edge
% 0 0 270 2 0 90 1 fat_edge
2 0 90 0 0 270  1 fat_edge
0 0 180 0.5 -2 180 1 fat_edge
0.5 -2 90 1.5 -1.3 180 0.5 fat_edge
1.5 -1.3 270 2.5 -2 270 0.7 fat_edge
2.5 -2 90 0.5 -2 270 1 fat_edge
2.5 -2 0 3 -0.75 0 1 fat_edge
3 -0.75 270 1.5 -1.3 0 0.7 fat_edge
3 -0.75 180 1.5 -1.3 90 0.7 fat_edge
3 -0.75 90 2 0 0 0.5 fat_edge

0 0 90 fat_vertex
0 0 180 fat_vertex
0 0 270 fat_vertex
2 0 0 fat_vertex
2 0 90 fat_vertex
2 0 270 fat_vertex
0.5 -2 180 fat_vertex
0.5 -2 90 fat_vertex
2.5 -2 90 fat_vertex
2.5 -2 270 fat_vertex
1.5 -1.3 0 fat_vertex
1.5 -1.3 90 fat_vertex
1.5 -1.3 180 fat_vertex
1.5 -1.3 270 fat_vertex
3 -0.75 0 fat_vertex
3 -0.75 90 fat_vertex
3 -0.75 180 fat_vertex
3 -0.75 270 fat_vertex

5 0 translate
0 0 90 2 0 270 1 fat_edge
% 0 0 270 2 0 90 1 fat_edge
2 0 90 0 0 270  1 fat_edge

0 0 180 0.5 -2 180 1 fat_edge
0.5 -2 90 1.5 -1.3 180 0.5 fat_edge
1.5 -1.3 270 2.5 -2 270 0.7 fat_edge
2.5 -2 90 0.5 -2 270 1 fat_edge
2.5 -2 0 3 -0.75 0 1 fat_edge
3 -0.75 270 1.5 -1.3 0 0.7 fat_edge
3 -0.75 180 1.5 -1.3 90 0.7 fat_edge
3 -0.75 90 2 0 0 0.5 fat_edge

0 0 90 fat_vertex
0 0 180 fat_vertex
0 0 270 fat_vertex
2 0 0 fat_vertex
2 0 90 fat_vertex
2 0 270 fat_vertex
0.5 -2 180 fat_vertex
0.5 -2 90 fat_vertex
2.5 -2 90 fat_vertex
2.5 -2 270 fat_vertex
1.5 -1.3 0 fat_vertex
1.5 -1.3 90 fat_vertex
1.5 -1.3 180 fat_vertex
1.5 -1.3 270 fat_vertex
3 -0.75 0 fat_vertex
3 -0.75 90 fat_vertex
3 -0.75 180 fat_vertex
3 -0.75 270 fat_vertex

0 0 extra_fat_triangle
2 0 extra_fat_triangle_left
0.5 -2 extra_fat_triangle
1.5 -1.3 extra_fat_vertex
2.5 -2 extra_fat_triangle_left
3 -0.75 extra_fat_vertex

grestore
%eof

Любопитното е, че .pdf се показва неправилно само когато е преоразмерен до определени конкретни размери (или: показва се правилно при определени размери). Май не мога да предвидя кога ще проработи.

Ето как се показва (част от изображението) правилно:

правилно изображение

И тук е преоразмерен и се показва неправилно:

неправилно изображение
(източник: dannyc на math.uchicago.edu)

Имайте предвид, че тези изображения са .jpg, получени от .pdf. Ако запишете кода по-горе като .eps файл и го отворите с Preview на Mac, предполагам, че той ще прояви същата патология, както на моя компютър.

Всеки съвет би бил много добре дошъл. Не знам достатъчно (или: нищо) за това как кривите на Безие се показват в .pdf, за да знам какъв може да е проблемът тук.


person Danny Calegari    schedule 03.01.2013    source източник


Отговори (1)


Ето съкратен случай, който показва същия проблем с изобразяването:

%!PS-Adobe-2.0 EPSF-2.0
%%BoundingBox: 0 0 400 200
gsave 50 50 scale 1 3 translate

0 setgray
0.05 setlinewidth
newpath
0 0 moveto 
0 1 2 -1 2 0 curveto
stroke

grestore
%eof

Не може да стане много по-просто от това: път на Безие само с две точки, всички с цели числа.

Изглежда, че рендърът на Apple има известна числена нестабилност около центъра на кривата. Ако промените една от контролните точки на кривата с малка сума, грешката не се случва:

0 1.00001 2 -1 2 0 curveto

Така че има заобиколно решение: във вашия оригинален файл добавете малък коефициент на изглаждане (част от градуса) към един от ъглите във всяка крива.

Смених всяко /angle1 exch def на 0.01 add /angle1 exch def и при мен проработи. Ето EPS файла и получения PDF файл.

(Разбира се, това не би трябвало да е необходимо, но докато не подадете сигнал за грешка и Apple не пусне корекция, може да е най-целесъобразното решение.)

person Kurt Revis    schedule 03.01.2013
comment
Благодаря за предложението Опитах го, но изглежда, че грешката продължава да съществува в моята система. Има ли някаква документация за алгоритъма, който Apple действително използва (или би използвал, ако Preview работи правилно)? - person Danny Calegari; 03.01.2013
comment
Ха - когато се опитам да подам доклад за грешка в Apple, получавам грешка при влизане: Възникна грешка. Моля, съобщете за грешката на Apple Inc., като изпратите подробностите за грешката по имейл на [email protected]. Усещам порочен кръг тук. . . - person Danny Calegari; 03.01.2013
comment
Редактиран отговор за добавяне на повече подробности относно заобиколното решение и връзки към EPS и PDF файловете. - person Kurt Revis; 04.01.2013