summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/metapost/venn/venn.mp
blob: 8f1ff12e9f304ec6a9e3b26bd6ca7e9afe589c6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
% venn.mp
%  MetaPost input file for venn diagrams.
%
% LICENSE
%  This is released under the LaTeX Project Public License. 
%
% HISTORY
% 2001-Apr-15 Jim Hefferon jim@joshua.smcvt.edu Written
%

%defaultscale := 9pt/fontsize defaultfont;

newinternal venn_width, venn_height;
venn_width := 100pt; venn_height := .618venn_width;
newinternal venn_circle_diameter;
venn_circle_diameter := .5venn_height;
newinternal venn_pen;
venn_pen := 0.4pt;
vardef venn_shade = .9white enddef;
vardef venn_unshade = white enddef;

path venn_box; % box that borders a Venn diagram; `U'
  venn_box = (0,0)--(venn_width,0)--(venn_width,venn_height)
                --(0,venn_height)--cycle;
newinternal venn_circle_left_shift,
            venn_circle_right_shift,
	    venn_circle_top_shift,
	    venn_circle_bottom_shift;
venn_circle_left_shift := .5venn_width;
venn_circle_right_shift := venn_width-venn_circle_left_shift;
venn_circle_top_shift := .5venn_height;
venn_circle_bottom_shift := venn_height-venn_circle_bottom_shift;


% ..... venn_color .......
%  Return either venn_shade or venn_unshade, as chosen.
% ARGS
%  b  A boolean
% RETURNS
%  a color
% USAGE
%  fill circle withcolor venn_color(true);
%
def venn_color(expr b) =
  if b: venn_shade else: venn_unshade fi
enddef;

% ...... draw_venn_none ...........
%  Draw a Venn diagram with no enclosed circles (just the universal set)
% ARGS
%  univ  A boolean; color the set or not?
% RETURNS
%  --
% USAGE
%  draw_venn_none(true); 
% draws a shaded set.
%
def draw_venn_none(expr univ)text t = 
  begingroup
    fill venn_box t withcolor venn_color(univ);    
    pickup pensquare scaled venn_pen; draw venn_box t;
  endgroup
enddef;

% ...... draw_venn_one ...........
%  Draw a Venn diagram with one enclosed circle
% ARGS
%  univ  A boolean; color the universal set or not?
%  cl  A boolean; color the circle?
% RETURNS
%  --
% USAGE
%  draw_venn_one(true,false); 
% draws a shaded set with the unshaded circle.
%
def draw_venn_one(expr univ, cl)text t = 
  begingroup
    venn_circle_left_shift := .5venn_width;
    venn_circle_right_shift := venn_width-venn_circle_left_shift;
    venn_circle_top_shift := .5venn_height;
    venn_circle_bottom_shift := venn_height-venn_circle_top_shift;

    fill venn_box t withcolor venn_color(univ);    
    pickup pensquare scaled venn_pen; draw venn_box t;

    save circle; path circle;
      circle = fullcircle scaled venn_circle_diameter
                 shifted (venn_circle_left_shift,venn_circle_top_shift) t;
    fill circle withcolor venn_color(cl);
    pickup pencircle scaled venn_pen; draw circle;
  endgroup
enddef;

% ...... draw_venn_two ...........
%  Draw a Venn diagram with two enclosed circles
% ARGS
%  univ  A boolean; color the universal set or not?
%  cl  A boolean; color the left circle?
%  lr  A boolean; color the intersection wedge?
%  cr  A boolean; color the right circle?
% RETURNS
%  --
% USAGE
%  draw_venn_two(true,false,true,false) shifted (2in,1in); 
% draws a diagram, shifted.
% NOTE 
%  The trick here is to use mpost's buildcycle to define the
% path `lr' outlining the intersection of the left and right
% circles.  Below the left circle is defined to be rotated -180.
% That's because otherwise the intersection with the right
% circle occurs on top early in the path, and on bottom late in
% the path, and so the left of the lr region crosses through the
% `point 0 of circle_left' boundary, which confuses buildcycle.
% So, it's a hack.
%
def draw_venn_two(expr univ, cl, lr, cr)text t = 
  begingroup
    venn_circle_left_shift := .4venn_width;
    venn_circle_right_shift := venn_width-venn_circle_left_shift;
    venn_circle_top_shift := .5venn_height;
    venn_circle_bottom_shift := venn_height-venn_circle_top_shift;

    fill venn_box t withcolor venn_color(univ);    
    pickup pensquare scaled venn_pen; draw venn_box t;

    save circle_left, circle_right; path circle_left, circle_right;
      circle_left = fullcircle rotated -180 scaled venn_circle_diameter
                     shifted (venn_circle_left_shift,venn_circle_top_shift) t;
      circle_right = fullcircle scaled venn_circle_diameter
                     shifted (venn_circle_right_shift,venn_circle_top_shift) t;
    save area_lr; path area_lr;
    area_lr = buildcycle(circle_left,circle_right);
  
    fill circle_left withcolor venn_color(cl);
    fill circle_right withcolor venn_color(cr);
    fill area_lr withcolor venn_color(lr);
    pickup pencircle scaled venn_pen;
    draw circle_left; draw circle_right;
  endgroup
enddef;



% ...... draw_venn_three ...........
%  Draw a Venn diagram with three enclosed circles
% ARGS
%  univ  A boolean; color the universal set or not?
%  cl  A boolean; color the left circle?
%  lr  A boolean; color the intersection wedge?
%  cr  A boolean; color the right circle?
%  lb  A boolean; color the intersection of left and bot right circles?
%  rb  A boolean; color the intersection of right and bot circles?
%  lrb  A boolean; color the intersection of all three circles?
%  cb  A boolean; color the bottom circle?
% RETURNS
%  --
% USAGE
%  draw_venn_three(true,false, ...) shifted (2in,1in); 
% draws a diagram, shifted.
% NOTE 
% The  trick here is to use mpost's buildcycle to define the
% paths `lr' (outlining the intersection of the left and right
% circles), `rb', `lb', and `lrb'.
% To do that I had to fiddle with the times along the circles.
% So, it's a hack.
%
def draw_venn_three(expr univ, cl, lr, cr, lb, rb, lrb, cb)text t = 
  begingroup
    venn_circle_left_shift := .4venn_width;
    venn_circle_right_shift := venn_width-venn_circle_left_shift;
    venn_circle_top_shift := .63venn_height;
    venn_circle_bottom_shift := venn_height-venn_circle_top_shift;

    fill venn_box t withcolor venn_color(univ);    
    pickup pensquare scaled venn_pen; draw venn_box t;

    save circle_left, circle_right, circle_bottom;
    path circle_left, circle_right, circle_bottom;
    circle_left = (reverse fullcircle) rotated -180 scaled venn_circle_diameter
                   shifted (venn_circle_left_shift,venn_circle_top_shift) t;
    circle_right = (reverse fullcircle) scaled venn_circle_diameter
                   shifted (venn_circle_right_shift,venn_circle_top_shift) t;
    circle_bottom = (reverse fullcircle) rotated -90 scaled venn_circle_diameter
                   shifted (.5venn_width,venn_circle_bottom_shift) t;
    save area_lr, area_lb, area_rb, area_lrb;
    path area_lr, area_lb, area_rb, area_lrb;
    area_lr = buildcycle(circle_left,circle_right);
    area_lb = buildcycle(circle_left,circle_bottom);
    area_rb = buildcycle(circle_right,circle_bottom);
    area_lrb = buildcycle(circle_left,circle_right,circle_bottom);

    fill circle_left withcolor venn_color(cl);
    fill circle_right withcolor venn_color(cr);
    fill circle_bottom withcolor venn_color(cb);
    fill area_lr withcolor venn_color(lr);
    fill area_lb withcolor venn_color(lb);
    fill area_rb withcolor venn_color(rb);
    fill area_lrb withcolor venn_color(lrb);
    pickup pencircle scaled venn_pen;
    draw circle_left; draw circle_right; draw circle_bottom;
  endgroup
enddef;


% test: This works for me under Linux (2001-Apr-15)
%  > mpost venn
%  > tex mproof venn.0
%  > dvips -Pwww -omproof.ps mproof
% results in a document mproof.ps in PostScript that I can see with
% > gv mproof.ps (type that from an XWindow xterm).

% To run the test, uncomment the next five lines (including the `end').
%beginfig(0);
%  draw_venn_three(false,true,false,true,false,true,true,false);
%  draw_venn_three(false,true,false,true,false,true,true,false) shifted (2in,3in);
%endfig;
%end