1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17\startluacode
18
19
20
21
22
23
24
25
26
27 do
28
29 local function sum(t)
30 local n = 0
31 for i=1,#t do
32 n = n + t[i]
33 end
34 return n
35 end
36
37 local function checked(data)
38 if data then
39 local n = #data
40 for i=1,n do
41 data[i][i] = 0
42 end
43 for i=1,n do
44 local di = data[i]
45 for j=i+1,n do
46 local dj = data[j]
47 local dji = dj[i]
48 if not dji then
49 dji = 0
50 dj[i] = 0
51 end
52 di[j] = dji
53 end
54 end
55 return data
56 else
57 return { }
58 end
59 end
60
61 local data, list = nil, nil
62
63 function mp.lmt_overlap_prepare()
64 data = checked(metapost.getparameter { "data" })
65 list = { }
66 for i=1,#data do
67 list[i] = sum(data[i])
68 end
69 end
70
71 function mp.lmt_overlap_reset()
72 data = nil
73 list = nil
74 end
75
76 function mp.lmt_overlap_n()
77 return #list
78 end
79
80 function mp.lmt_overlap_data(i, j)
81 if j then
82 return data[i][j]
83 else
84 return list[i]
85 end
86 end
87
88 local injectstring = mp.inject.string
89
90 function mp.lmt_overlap_text(i, j)
91 injectstring(data[i][j] or "")
92 end
93
94 function mp.lmt_overlap_label(i)
95 local labels = metapost.getparameter { "labels" }
96 injectstring(labels and labels[i] or "")
97 end
98
99 function mp.lmt_overlap_color(i)
100 local colors = metapost.getparameter { "colors" }
101 injectstring(colors and colors[i] or "darkgray")
102 end
103
104 function mp.lmt_overlap_total()
105 return sum(list)
106 end
107
108 end
109\stopluacode
110
111\startMPextensions
112
113presetparameters "overlap" [
114 options = "paths,lines",
115 gap = 4,
116 subgap = 2,
117 offset = 8,
118 color = "darkgray",
119 alternative = "circular",
120 colors = {
121 "darkred",
122 "darkgreen",
123 "darkblue",
124 "darkyellow",
125 "darkmagenta",
126 "darkcyan"
127 },
128] ;
129
130def lmt_overlap = applyparameters "overlap" "lmt_do_overlap" enddef ;
131
132vardef lmt_do_overlap_circular =
133
134 astep := 360 steps ;
135
136 p := fullcircle scaled steps ;
137 r := origin -- (2steps,0) ;
138
139 start := 0 ;
140 stop := 0 ;
141 for i=1 upto n:
142 stop := start lua.mp.lmt_overlap_data(i) ;
143 first := start ;
144 last := stop ;
145 for j=1 upto n:
146 if i <> j :
147 last := first lua.mp.lmt_overlap_data(i,j) ;
148 a := p intersectionpoint (r rotated (first astep 0.1)) ;
149 b := p intersectionpoint (r rotated (last astep 0.1)) ;
150 qq[i][j] := (p cutafter b) cutbefore a ;
151 first := last subgap ;
152 fi ;
153 endfor ;
154 start := stop gap (n 1) subgap ;
155 endfor ;
156
157 if hasoption "options" "paths" :
158
159 for i=1 upto n :
160 for j=1 upto n :
161 if i <> j :
162 q := qq[i][j] ;
163 freelabeloffset := getparameter "offset" ;
164 freelabel(lua.mp.lmt_overlap_text(i,j), point .5 along q, origin) ;
165 if i < j :
166 s := qq[j][i] ;
167 a := point length(q) of q ;
168 b := point 0 of s ;
169 c := point length(s) of s ;
170 d := point 0 of q ;
171 q := q & a .. controls origin and origin .. b & s & c .. controls origin and origin .. d -- cycle ;
172 fill q withcolor lua.mp.lmt_overlap_color(i) withtransparency (1,.8) ;
173 fi ;
174 fi ;
175 endfor ;
176 endfor ;
177
178 fi ;
179
180 if hasoption "options" "lines" :
181
182 start := 0 ;
183 stop := 0 ;
184 for i=1 upto n:
185 stop := start lua.mp.lmt_overlap_data(i) (n 2) subgap ;
186 a := p intersectionpoint (r rotated (start astep)) ;
187 b := p intersectionpoint (r rotated (stop astep)) ;
188 q := (p cutbefore a) cutafter b ;
189 freelabeloffset := getparameterdefault "textoffset" (4 getparameter "offset") ;
190 freelabel(lua.mp.lmt_overlap_label(i), point .5 along q, origin) ;
191 draw q withcolor white withpen pencircle scaled 5 ;
192 draw q withcolor getparameter "color" withpen pencircle scaled 5 ;
193 start := stop gap subgap ;
194 endfor ;
195
196 fi ;
197
198enddef ;
199
200vardef lmt_do_overlap_linear =
201 astep := 1 ;
202
203 p := origin -- (astep steps,0) ;
204 r := origin -- (0,astep steps) ;
205
206 start := 0 ;
207 stop := 0 ;
208 for i=1 upto n:
209 stop := start lua.mp.lmt_overlap_data(i) ;
210 first := start ;
211 last := stop ;
212 for j=1 upto n:
213 if i <> j :
214 last := first lua.mp.lmt_overlap_data(i,j) ;
215 qq[i][j] := (first astep,0) -- (last astep,0) ;
216 first := last subgap ;
217 fi ;
218 endfor ;
219 start := stop gap (n 1) subgap ;
220 endfor ;
221
222 if hasoption "options" "paths" :
223
224 for i=1 upto n :
225 for j=1 upto n :
226 if i < j :
227 qq[i][j] := qq[i][j] { up } .. { down } qq[j][i] { up } .. { down} cycle ;
228 fill qq[i][j] withcolor lua.mp.lmt_overlap_color(i) withtransparency (1,.8) ;
229 fi ;
230 endfor ;
231 endfor ;
232
233 for i=1 upto n :
234 for j=1 upto n :
235 if i < j :
236 t := thelabel(lua.mp.lmt_overlap_text(i,j), (center topboundary qq[i][j]) ) ;
237 fill boundingbox t enlarged (ExHeight2) withcolor white ;
238 draw t ;
239 fi ;
240 endfor ;
241 endfor ;
242
243 fi ;
244
245 if hasoption "options" "lines" :
246
247 start := 0 ;
248 stop := 0 ;
249 for i=1 upto n:
250 stop := start lua.mp.lmt_overlap_data(i) (n 2) subgap ;
251 q := (start astep,0) -- (stop astep,0) ;
252 freelabeloffset := getparameterdefault "textoffset" (4 getparameter "offset") ;
253 label.bot(lua.mp.lmt_overlap_label(i), (point .5 along q) shifted (0, freelabeloffset4)) ;
254 draw q withcolor white withpen pencircle scaled 5 ;
255 draw q withcolor getparameter "color" withpen pencircle scaled 5 ;
256 start := stop gap subgap ;
257 endfor ;
258
259 fi ;
260
261enddef ;
262
263vardef lmt_do_overlap =
264 image (
265
266 pushparameters "overlap" ;
267
268 save p, q, r, s, qq, a, b, c, d, t, n, gap, subgap, steps, astep, start, stop, first, last ;
269 path p, q, r, s, qq[][] ;
270 pair a, b, c, d ;
271 picture t ;
272 numeric n, gap, subgap, steps, astep, start, stop, first, last ;
273 save freelabeloffset; freelabeloffset := 8 ;
274 interim linecap := butt;
275 interim linejoin := squared;
276
277 lua.mp.lmt_overlap_prepare() ;
278
279 n := lua.mp.lmt_overlap_n();
280 gap := getparameter "gap" ;
281 subgap := getparameter "subgap" ;
282 steps := lua.mp.lmt_overlap_total() (n gap) n (n 1) subgap ;
283
284 if ((getparameter "alternative") = "linear") or ((getparameter "alternative") = "line") :
285 lmt_do_overlap_linear ;
286 else :
287 lmt_do_overlap_circular ;
288 fi ;
289
290 lua.mp.lmt_overlap_reset() ;
291
292 popparameters ;
293 )
294enddef ;
295
296\stopMPextensions
297
298\continueifinputfile{metaimpexperiments.mkxl}
299
300
301
302\usemodule[articlebasic]
303
304\starttext
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330\startbuffer
331\startMPcode{doublefun}
332 draw lmt_overlap [
333 alternative = "circular",
334 data = { { }, { 10 }, { 30, 10 }, { 10, 20, 5 }, { 20, 10, 15, 5 } },
335 labels = { "one", "two", "three", "four", "five" }
336 ] ;
337\stopMPcode
338\stopbuffer
339
340\startlinecorrection[blank]
341 \getbuffer
342\stoplinecorrection
343
344\startbuffer
345\startMPcode{doublefun}
346 draw lmt_overlap [
347 alternative = "linear",
348 data = { { }, { 10 }, { 30, 10 }, { 10, 20, 5 }, { 20, 10, 15, 5 } },
349 labels = { "one", "two", "three", "four", "five" }
350 ] ;
351\stopMPcode
352\stopbuffer
353
354\startlinecorrection[blank]
355 \getbuffer
356\stoplinecorrection
357
358\stoptext
359 |