summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/meta-imp-experiments.mkxl
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/meta-imp-experiments.mkxl')
-rw-r--r--tex/context/base/mkiv/meta-imp-experiments.mkxl360
1 files changed, 360 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/meta-imp-experiments.mkxl b/tex/context/base/mkiv/meta-imp-experiments.mkxl
new file mode 100644
index 000000000..6b43ba676
--- /dev/null
+++ b/tex/context/base/mkiv/meta-imp-experiments.mkxl
@@ -0,0 +1,360 @@
+%D \module
+%D [ file=meta-imp-experiments,
+%D version=2020.03.18,
+%D title=\METAPOST\ Graphics,
+%D subtitle=Experimental Graphics,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+%D This library implements some experimental functionality that eventually
+%D might end up someplace else.
+
+\startluacode
+
+ -- I decided to play with this kind of graphics after I read an article in a Dutch
+ -- popular science journal. It was an article about virusus in the mids of the time
+ -- when covid raged, so it also was a distraction.
+
+ -- This is a typical case of first prototyping it in Lua using the 'context' command
+ -- to generate MetaPost code and when that worked okay do it the following way. The
+ -- way data is passed is a bit messy.
+
+ do
+
+ local function sum(t)
+ local n = 0
+ for i=1,#t do
+ n = n + t[i]
+ end
+ return n
+ end
+
+ local function checked(data)
+ if data then
+ local n = #data
+ for i=1,n do
+ data[i][i] = 0
+ end
+ for i=1,n do
+ local di = data[i]
+ for j=i+1,n do
+ local dj = data[j]
+ local dji = dj[i]
+ if not dji then
+ dji = 0
+ dj[i] = 0
+ end
+ di[j] = dji
+ end
+ end
+ return data
+ else
+ return { }
+ end
+ end
+
+ local data, list = nil, nil
+
+ function mp.lmt_overlap_prepare()
+ data = checked(metapost.getparameter { "data" })
+ list = { }
+ for i=1,#data do
+ list[i] = sum(data[i])
+ end
+ end
+
+ function mp.lmt_overlap_reset()
+ data = nil
+ list = nil
+ end
+
+ function mp.lmt_overlap_n()
+ return #list
+ end
+
+ function mp.lmt_overlap_data(i, j)
+ if j then
+ return data[i][j]
+ else
+ return list[i]
+ end
+ end
+
+ local injectstring = mp.inject.string
+
+ function mp.lmt_overlap_text(i, j)
+ injectstring(data[i][j] or "")
+ end
+
+ function mp.lmt_overlap_label(i)
+ local labels = metapost.getparameter { "labels" }
+ injectstring(labels and labels[i] or "")
+ end
+
+ function mp.lmt_overlap_color(i)
+ local colors = metapost.getparameter { "colors" }
+ injectstring(colors and colors[i] or "darkgray")
+ end
+
+ function mp.lmt_overlap_total()
+ return sum(list)
+ end
+
+ end
+\stopluacode
+
+\startMPextensions
+
+presetparameters "overlap" [
+ options = "paths,lines",
+ gap = 4,
+ subgap = 2,
+ offset = 8,
+ color = "darkgray",
+ alternative = "circular",
+ colors = {
+ "darkred",
+ "darkgreen",
+ "darkblue",
+ "darkyellow",
+ "darkmagenta",
+ "darkcyan"
+ },
+] ;
+
+def lmt_overlap = applyparameters "overlap" "lmt_do_overlap" enddef ;
+
+vardef lmt_do_overlap_circular =
+
+ astep := 360 / steps ;
+
+ p := fullcircle scaled steps ;
+ r := origin -- (2*steps,0) ;
+
+ start := 0 ;
+ stop := 0 ;
+ for i=1 upto n:
+ stop := start + lua.mp.lmt_overlap_data(i) ;
+ first := start ;
+ last := stop ;
+ for j=1 upto n:
+ if i <> j :
+ last := first + lua.mp.lmt_overlap_data(i,j) ;
+ a := p intersectionpoint (r rotated (first * astep + 0.1)) ; % the 0.1 is somehow needed, why
+ b := p intersectionpoint (r rotated (last * astep - 0.1)) ; % the 0.1 is somehow needed, why
+ qq[i][j] := (p cutafter b) cutbefore a ;
+ first := last + subgap ;
+ fi ;
+ endfor ;
+ start := stop + gap + (n - 1) * subgap ;
+ endfor ;
+
+ if hasoption "options" "paths" :
+
+ for i=1 upto n :
+ for j=1 upto n :
+ if i <> j :
+ q := qq[i][j] ;
+ freelabeloffset := getparameter "offset" ;
+ freelabel(lua.mp.lmt_overlap_text(i,j), point .5 along q, origin) ;
+ if i < j :
+ s := qq[j][i] ;
+ a := point length(q) of q ;
+ b := point 0 of s ;
+ c := point length(s) of s ;
+ d := point 0 of q ;
+ q := q & a .. controls origin and origin .. b & s & c .. controls origin and origin .. d -- cycle ;
+ fill q withcolor lua.mp.lmt_overlap_color(i) withtransparency (1,.8) ;
+ fi ;
+ fi ;
+ endfor ;
+ endfor ;
+
+ fi ;
+
+ if hasoption "options" "lines" :
+
+ start := 0 ;
+ stop := 0 ;
+ for i=1 upto n:
+ stop := start + lua.mp.lmt_overlap_data(i) + (n - 2) * subgap ;
+ a := p intersectionpoint (r rotated (start * astep)) ;
+ b := p intersectionpoint (r rotated (stop * astep)) ;
+ q := (p cutbefore a) cutafter b ;
+ freelabeloffset := getparameterdefault "textoffset" (4 * getparameter "offset") ;
+ freelabel(lua.mp.lmt_overlap_label(i), point .5 along q, origin) ;
+ draw q withcolor white withpen pencircle scaled 5 ;
+ draw q withcolor getparameter "color" withpen pencircle scaled 5 ;
+ start := stop + gap + subgap ;
+ endfor ;
+
+ fi ;
+
+enddef ;
+
+vardef lmt_do_overlap_linear =
+ astep := 1 ; % 1.25
+
+ p := origin -- (astep * steps,0) ;
+ r := origin -- (0,astep * steps) ;
+
+ start := 0 ;
+ stop := 0 ;
+ for i=1 upto n:
+ stop := start + lua.mp.lmt_overlap_data(i) ;
+ first := start ;
+ last := stop ;
+ for j=1 upto n:
+ if i <> j :
+ last := first + lua.mp.lmt_overlap_data(i,j) ;
+ qq[i][j] := (first * astep,0) -- (last * astep,0) ;
+ first := last + subgap ;
+ fi ;
+ endfor ;
+ start := stop + gap + (n - 1) * subgap ;
+ endfor ;
+
+ if hasoption "options" "paths" :
+
+ for i=1 upto n :
+ for j=1 upto n :
+ if i < j :
+ qq[i][j] := qq[i][j] { up } .. { down } qq[j][i] { up } .. { down} cycle ;
+ fill qq[i][j] withcolor lua.mp.lmt_overlap_color(i) withtransparency (1,.8) ;
+ fi ;
+ endfor ;
+ endfor ;
+
+ for i=1 upto n :
+ for j=1 upto n :
+ if i < j :
+ t := thelabel(lua.mp.lmt_overlap_text(i,j), (center topboundary qq[i][j]) ) ;
+ fill boundingbox t enlarged (ExHeight/2) withcolor white ;
+ draw t ;
+ fi ;
+ endfor ;
+ endfor ;
+
+ fi ;
+
+ if hasoption "options" "lines" :
+
+ start := 0 ;
+ stop := 0 ;
+ for i=1 upto n:
+ stop := start + lua.mp.lmt_overlap_data(i) + (n - 2) * subgap ;
+ q := (start * astep,0) -- (stop * astep,0) ;
+ freelabeloffset := getparameterdefault "textoffset" (4 * getparameter "offset") ;
+ label.bot(lua.mp.lmt_overlap_label(i), (point .5 along q) shifted (0,- freelabeloffset/4)) ;
+ draw q withcolor white withpen pencircle scaled 5 ;
+ draw q withcolor getparameter "color" withpen pencircle scaled 5 ;
+ start := stop + gap + subgap ;
+ endfor ;
+
+ fi ;
+
+enddef ;
+
+vardef lmt_do_overlap =
+ image (
+
+ lmt_load_mlib_cnt ;
+
+ pushparameters "overlap" ;
+
+ save p, q, r, s, qq, a, b, c, d, t, n, gap, subgap, steps, astep, start, stop, first, last ;
+ path p, q, r, s, qq[][] ;
+ pair a, b, c, d ;
+ picture t ;
+ numeric n, gap, subgap, steps, astep, start, stop, first, last ;
+ save freelabeloffset; freelabeloffset := 8 ;
+ interim linecap := butt;
+ interim linejoin := squared;
+
+ lua.mp.lmt_overlap_prepare() ;
+
+ n := lua.mp.lmt_overlap_n();
+ gap := getparameter "gap" ;
+ subgap := getparameter "subgap" ;
+ steps := lua.mp.lmt_overlap_total() + (n * gap) + n * (n - 1) * subgap ;
+
+ if ((getparameter "alternative") = "linear") or ((getparameter "alternative") = "line") :
+ lmt_do_overlap_linear ;
+ else :
+ lmt_do_overlap_circular ;
+ fi ;
+
+ lua.mp.lmt_overlap_reset() ;
+
+ popparameters ;
+ )
+enddef ;
+
+\stopMPextensions
+
+\continueifinputfile{meta-imp-experiments.mkxl}
+
+% \useMPlibrary[experiments]
+
+\usemodule[article-basic]
+
+\starttext
+
+% todo: datafile: { data = { }, labels = { } }
+
+% % data = {
+% % { 0, 10, 30, 10, 20 },
+% % { 10, 0, 10, 20, 10 },
+% % { 30, 10, 0, 5, 15 },
+% % { 10, 20, 5, 0, 5 },
+% % { 20, 10, 15, 5, 0 }
+% % },
+% % data = {
+% % { 0 },
+% % { 10, 0 },
+% % { 30, 10, 0 },
+% % { 10, 20, 5, 0 },
+% % { 20, 10, 15, 5, 0 }
+% % },
+% data = {
+% { },
+% { 10 },
+% { 30, 10 },
+% { 10, 20, 5 },
+% { 20, 10, 15, 5 }
+% },
+
+\startbuffer
+\startMPcode{doublefun}
+ draw lmt_overlap [
+ alternative = "circular",
+ data = { { }, { 10 }, { 30, 10 }, { 10, 20, 5 }, { 20, 10, 15, 5 } },
+ labels = { "one", "two", "three", "four", "five" }
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+\startbuffer
+\startMPcode{doublefun}
+ draw lmt_overlap [
+ alternative = "linear",
+ data = { { }, { 10 }, { 30, 10 }, { 10, 20, 5 }, { 20, 10, 15, 5 } },
+ labels = { "one", "two", "three", "four", "five" }
+ ] ;
+\stopMPcode
+\stopbuffer
+
+\startlinecorrection[blank]
+ \getbuffer
+\stoplinecorrection
+
+\stoptext