Пойдя настолько далеко, насколько это практически возможно с pic, postscript действительно является естественным выбором для этого.
Хорошо, я еще не решил маркировку, но вот обобщенная диаграмма. Оказывается, вы просто помещаете центры в вершины правильного многоугольника для этого n .
Но некоторые из этих мест становятся реальными маленькими. Так что я думаю о некотором шаблоне маркированных дуг, растущих по спирали. Возможно, радиус метки должен отражать глубину обозначенной перегородки ...
Редактировать: Я переработал код, поэтому в ревизии 1 есть симпатичная страница с 15 диаграммами.
Редактировать: Я только что получил образование в Википедии. Оказывается, то, что я называю диаграммой Венна с четырьмя ячейками, является , фактически, вообще не диаграммой Венна .
Это диаграмма Эйлера. Проблема в том, что нигде нельзя получить пересечение двух областей в одиночку с противоположных сторон диаграммы. Диаграмма real 4 ячейки становится странной, независимо от того, как вы это делаете. Таким образом, объем ответа уменьшен по сравнению с тем, что я преследовал в последних двух изменениях.
Для диаграммы с двумя кругами лучшее расположение, которое я могу найти, определяется пересечением радиусов от центра диаграммы через центры окружностей к краям, с определяющими кругами, помещенными в центры окружностей.
Для 3-круговой диаграммы лучшее расположение, которое я могу найти, определяется пересечениями радиусов (и повернутых радиусов) с приближением повернутых треугольников к окружностям и неповоротным треугольникам соответственно.
Вариант кода можно найти в предыдущей редакции этого ответа. Выложил расширенную версию для usenet в теме геодезические цветы . Но поскольку этот ответ излишним (и на самом деле он не рисует никаких ярлыков и не возвращает их местоположения) и недостаточным для обобщенных диаграмм Венна real , мне придется подрезать большую часть багажа, прежде чем подвергать это вопрос к более длинным блокам кода.
Редактировать: Я думаю, что это почти облизано. Эта программа содержит только те части предыдущей программы, которые необходимы для создания 2- и 3-диаграмм Венна с маленькими кружочками в «идеальных» местах меток. Для диаграммы с двумя ячейками решение действительно тривиально (удваивает определяющий радиус). Для диаграммы с 3 ячейками решение составляет cos (60) * радиус окружности + определяющий радиус , либо умножение сначала или добавление сначала.
Редактировать: Наконец, ярлыки. Требовалась некоторая хитрость в последнюю минуту, так как я использовал вращение матрицы, чтобы найти точки. Это означало, что когда я пытался печатать этикетки, все они были в странной ориентации. Так что процедура "centershow" имеет немного больше, чем обычно. Он должен сбрасывать части масштабирования текущей матрицы преобразования, оставляя компоненты перевода в покое. Это означает, что где-то на раннем этапе выполнения мы должны хранить ориентированную матрицу в правильном масштабе.
( Редактировать: Еще один способ получить текст в вертикальном положении без изменения матрицы - это transform
расположение координат устройства, установка ориентированной матрицы (в любом масштабе или переводе!), itransform
точка возврата к «новым» пользовательским координатам, а затем moveto
.)
%!
%cp:xy rad circ -
/circ {
currentpoint newpath
2 copy 5 -1 roll 0 360 arc stroke
moveto
} def
%rad n poly [pointlist]
/poly {
1 dict begin exch /prad exch def
[ exch
0 exch 360 exch div 359.9 {
[ exch
dup cos prad mul exch
sin prad mul
]
} for
]
end
} def
%[list] rad subcirc -
/subcirc {
1 dict begin /crad exch def gsave
currentpoint translate
{ aload pop moveto crad circ } forall
grestore end
} def
%[list] locate -
%draw little circles around each point
/locate {
gsave
currentpoint translate
0 0 moveto 5 circ
{ aload pop moveto 5 circ } forall
grestore
} def
%cp:xy (string) cshow -
/cshow {
gsave
currentpoint translate %0 0 moveto
matrix currentmatrix
dup 0 normal 0 4 getinterval %reset rotation, keep translation
putinterval setmatrix
dup true charpath flattenpath pathbbox
3 -1 roll sub 3 1 roll sub
2 div exch -2 div moveto show
grestore
} def
%[list] [labels] label -
%print label text centered on each point
/label {
gsave
currentpoint translate
0 1 3 index length 1 sub {
2 index 1 index get aload pop moveto
2 copy get cshow pop
} for
pop pop
grestore
} def
%[x0 y0] [x1 y1] pyth-dist radius
/pyth-dist {
aload pop 3 -1 roll aload pop % x1 y1 x0 y0
exch % x1 y1 y0 x0
3 1 roll sub dup mul % x1 x0 dy^2
3 1 roll sub dup mul % dy^2 dx^2
add sqrt
} def
/rotw { 180 n div rotate } def
%cp:xy rad n venn -
%make the circles intersect the opposite point of def poly
/venn {
3 dict begin /n exch def /vrad exch def
vrad n poly
dup 0 get exch
dup length 2 idiv get
pyth-dist /crad exch def
%vrad crad n ven
vrad n poly crad subcirc %the Venn circles
[[0 0]] [(All)] label
n 2 eq {
%vrad 2 mul n poly locate
vrad 2 mul n poly
[(A) (B)] label
}{
n 3 eq {
%vrad crad 60 cos mul add n poly locate
vrad crad 60 cos mul add n poly
[ (A) (B) (C) ] label
%gsave rotw vrad crad add 60 cos mul n poly locate grestore
gsave rotw vrad crad add 60 cos mul n poly
[ (A^B) (B^C) (A^C) ] label
grestore
} if
} ifelse
end
} def
/normal matrix currentmatrix def
/in{72 mul}def
/Palatino-Roman 20 selectfont
4.25 in 8.25 in moveto
1 in 2 venn
4.25 in 3.5 in moveto
1 in 3 venn
showpage
И ghostscript выдает (gs -sDEVICE=jpeggray -sOutputFile=venlabel.jpg v4.ps
):