diff --git a/src/plot/sample.typ b/src/plot/sample.typ index 3ad881d..502b0c1 100644 --- a/src/plot/sample.typ +++ b/src/plot/sample.typ @@ -8,18 +8,24 @@ /// - fn (function): Function to sample of the form `(x) => y` or `(t) => (x, y)`, where /// `x` or `t` are `float` values within the domain specified by `domain`. /// - domain (domain): Domain of `fn` used as bounding interval for the sampling points. -/// - samples (int): Number of samples in domain. +/// - samples (int,str): Number of samples in domain or "INT" to use $"diam"("domain")$ +/// number of samples (passed as int). /// - sample-at (array): List of x values the function gets sampled at in addition /// to the `samples` number of samples. Values outsides the /// specified domain are legal. /// -> array: Array of (x, y) tuples #let sample-fn(fn, domain, samples, sample-at: ()) = { - assert(samples + sample-at.len() >= 2, - message: "You must at least sample 2 values") assert(type(domain) == array and domain.len() == 2, message: "Domain must be a tuple") let (lo, hi) = domain + if samples in ("int", "INT") { + samples = hi - lo + 1 + fn = n => { fn(int(n)) } + } + + assert(samples + sample-at.len() >= 2, + message: "You must at least sample 2 values") let y0 = (fn)(lo) let is-vector = type(y0) == array @@ -29,6 +35,7 @@ y0 = (y0, ) } + let pts = sample-at + range(0, samples).map(t => lo + t / (samples - 1) * (hi - lo)) pts = pts.sorted() diff --git a/tests/plot/sample/ref/1.png b/tests/plot/sample/ref/1.png new file mode 100644 index 0000000..debb9de Binary files /dev/null and b/tests/plot/sample/ref/1.png differ diff --git a/tests/plot/sample/test.typ b/tests/plot/sample/test.typ new file mode 100644 index 0000000..d3e794c --- /dev/null +++ b/tests/plot/sample/test.typ @@ -0,0 +1,26 @@ +#set page(width: auto, height: auto) +#import "/src/cetz.typ": * +#import "/src/lib.typ": * +#import "/tests/helper.typ": * + +#let f(n) = { + assert(type(n) == int) + range(1, n+1).map(n => calc.pow(1/3, n)).sum(default: 0) +} + +// Sample integer values +#test-case({ + plot.plot(size: (3, 3), x-tick-step: none, y-tick-step: none, + { + plot.add(domain: (0, 7), samples: "INT", f, mark: "x") + }) +}) + +// Take samples at specific points +#test-case({ + plot.plot(size: (3, 3), x-tick-step: none, y-tick-step: none, + { + plot.add(domain: (0, 1), samples: 2, x => x, mark: "x", + sample-at: (.1, .2, .3)) + }) +})