summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/mlib-ran.lmt
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2020-11-23 19:48:34 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2020-11-23 19:48:34 +0100
commit18499e46a49b8ccf4346686d1cf626ada33935b8 (patch)
treebd0ae7b601b323e20954c10c07598637d9403e00 /tex/context/base/mkiv/mlib-ran.lmt
parent4b089e589d39346a66a27d04f9857fe16e4b7b41 (diff)
downloadcontext-18499e46a49b8ccf4346686d1cf626ada33935b8.tar.gz
2020-11-23 18:39:00
Diffstat (limited to 'tex/context/base/mkiv/mlib-ran.lmt')
-rw-r--r--tex/context/base/mkiv/mlib-ran.lmt237
1 files changed, 0 insertions, 237 deletions
diff --git a/tex/context/base/mkiv/mlib-ran.lmt b/tex/context/base/mkiv/mlib-ran.lmt
deleted file mode 100644
index cb8645e8d..000000000
--- a/tex/context/base/mkiv/mlib-ran.lmt
+++ /dev/null
@@ -1,237 +0,0 @@
-if not modules then modules = { } end modules ['mlib-ran'] = {
- version = 1.001,
- comment = "companion to mlib-ctx.mkiv",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
-}
-
-local next = next
-local ceil, floor, random, sqrt, cos, sin, pi, max, min = math.ceil, math.floor, math.random, math.sqrt, math.cos, math.sin, math.pi, math.min, math.max
-local remove = table.remove
-
--- Below is a bit of rainy saturday afternoon hobyism, while listening to Judith
--- Owens redisCOVERed (came there via Leland Sklar who I have on a few live blurays;
--- and who is also on YT). (Also nice: https://www.youtube.com/watch?v=GXqasIRaxlA)
-
--- When Aditya pointed me to an article on mazes I ended up at poison distributions
--- which to me looks nicer than what I normally do, fill a grid and then randomize
--- the resulting positions. With some hooks this can be used for interesting patterns
--- too. A few links:
---
--- https://bost.ocks.org/mike/algorithms/#maze-generation
--- https://extremelearning.com.au/
--- https://www.jasondavies.com/maps/random-points/
--- http://devmag.org.za/2009/05/03/poisson-disk-sampling
-
--- The next function is quite close to what us discribed in the poisson-disk-sampling
--- link mentioned before. One can either use a one dimensional grid array or a two
--- dimensional one. The example code uses some classes dealing with points. In the
--- process I added some more control.
-
--- we could do without the samplepoints list
-
-local function poisson(width, height, mindist, newpointscount, initialx, initialy)
- local starttime = os.clock()
- local cellsize = mindist / sqrt(2)
- local nofwidth = ceil(width // cellsize)
- local nofheight = ceil(height // cellsize)
- local grid = lua.newtable(nofwidth,0) -- table.setmetatableindex("table")
- local firstx = initialx or random() * width
- local firsty = initialy or random() * height
- local firstpoint = { firstx, firsty, 1 }
- -- local samplepoints = { firstpoint }
- local processlist = { firstpoint }
- local nofprocesslist = 1
- local nofsamplepoints = 1
- local twopi = 2 * pi
-
- for i=1,nofwidth do
- local g = lua.newindex(nofheight,false)
- grid[i] = g
- end
-
- local x = floor(firstx // cellsize) + 1 -- lua indices
- local y = floor(firsty // cellsize) + 1 -- lua indices
-
- x = max(1, min(x, width - 1))
- y = max(1, min(y, height - 1))
-
- grid[x][y] = firstpoint
-
- -- The website shows graphic for this 5*5 grid snippet, if we use a one dimentional
- -- array then we could have one loop; a first version used a metatable trick so we
- -- had grid[i+gx][j+gy] but we no we also return the grid, so ... we now just check.
-
- -- There is no need for the samplepoints list as we can get that from the grid but
- -- instead we can store the index with the grid.
-
- while nofprocesslist > 0 do
- local point = remove(processlist,random(1,nofprocesslist))
- nofprocesslist = nofprocesslist - 1
- for i=1,newpointscount do -- we start at 1
- local radius = mindist * (random() + 1)
- local angle = twopi * random()
- local nx = point[1] + radius * cos(angle)
- local ny = point[2] + radius * sin(angle)
- if nx > 1 and ny > 1 and nx <= width and ny <= height then -- lua indices
- local gx = floor(nx // cellsize)
- local gy = floor(ny // cellsize)
- -- the 5x5 cells around the point
- for i=-2,2 do
- for j=-2,2 do
- local cell = grid[i + gx]
- if cell then
- cell = cell[j + gy]
- if cell and sqrt((cell[1] - nx)^2 + (cell[2] - ny)^2) < mindist then
- goto next
- end
- end
- end
- end
- -- local newpoint = { nx, ny }
- nofprocesslist = nofprocesslist + 1
- nofsamplepoints = nofsamplepoints + 1
- local newpoint = { nx, ny, nofsamplepoints }
- processlist [nofprocesslist] = newpoint
- -- samplepoints[nofsamplepoints] = newpoint
- grid[gx][gy] = newpoint
- end
- ::next::
- end
- end
-
- return {
- count = nofsamplepoints,
- -- points = samplepoints,
- grid = grid,
- time = os.clock() - starttime,
- }
-end
-
--- For now:
-
-local randomizers = utilities.randomizers or { }
-utilities.randomizers = randomizers
-randomizers.poisson = poisson
-
--- The MetaFun interface:
-
-local formatters = string.formatters
-local concat = table.concat
-
-local f_macro = formatters["%s(%N,%N);"]
-
-local f_macros = {
- [2] = formatters["%s(%N,%N);"],
- [3] = formatters["%s(%N,%N,%i);"],
- [4] = formatters["%s(%N,%N,%i,%i);"],
-}
-
-function grid_to_mp(t,f,n)
- local grid = t.grid
- local count = t.count
- local result = { }
- local r = 0
- local macro = f or "draw"
- local runner = f_macros[n or 2] or f_macros[2]
- for i=1,#grid do
- local g = grid[i]
- if g then
- for j=1,#g do
- local v = g[j]
- if v then
- r = r + 1
- result[r] = runner(macro,v[1],v[2],v[3],count)
- end
- end
- end
- end
- return concat(result, " ")
-end
-
-local getparameter = metapost.getparameter
-
-local function lmt_poisson()
- local initialx = getparameter { "initialx" }
- local initialy = getparameter { "initialy" }
- local width = getparameter { "width" }
- local height = getparameter { "height" }
- local distance = getparameter { "distance" }
- local count = getparameter { "count" }
-
- local result = poisson (
- width, height, distance, count,
- initialx > 0 and initialx or false,
- initialy > 0 and initialy or false
- )
-
- if result then
- logs.report("poisson","w=%N, h=%N, d=%N, c=%N, n=%i, runtime %.3f",
- width, height, distance, count, result.count, result.time
- )
- end
-
- return result
-end
-
-function mp.lmt_poisson_generate()
- local result = lmt_poisson()
- if result then
- return grid_to_mp (
- result,
- getparameter { "macro" },
- getparameter { "arguments" }
- )
- end
-end
-
--- -- some playing around showed no benefit
---
--- function points_to_mp(t,f)
--- local points = t.points
--- local count = t.count
--- local result = { }
--- local r = 0
--- local macro = f or "draw"
--- local runner = f_macros[n or 2] or f_macros[2]
--- for i=1,count do
--- local v = points[i]
--- r = r + 1
--- result[r] = runner(macro,v[1],v[2],v[3],count)
--- end
--- return concat(result, " ")
--- end
---
--- local result = false
--- local i, j, n = 0, 0, 0
---
--- function mp.lmt_poison_start()
--- result = lmt_poisson()
--- end
---
--- function mp.lmt_poisson_stop()
--- result = false
--- end
---
--- function mp.lmt_poisson_count()
--- return result and result.count or 0
--- end
---
--- function mp.lmt_poisson_get(i)
--- if result then
--- return mp.pair(result.points[i])
--- end
--- end
---
--- function mp.lmt_poisson_generate()
--- mp.lmt_poisson_start()
--- if result then
--- return grid_to_mp (
--- result,
--- getparameter { "macro" },
--- getparameter { "arguments" }
--- )
--- end
--- mp.lmt_poisson_stop()
--- end