From 30b5c194f80a562aedafc4d024d8ede29f4c3847 Mon Sep 17 00:00:00 2001 From: Guangxi Liu Date: Mon, 24 Feb 2025 18:46:27 +0800 Subject: [PATCH] fractusist:0.1.1 (#1815) Co-authored-by: liuguangxi --- packages/preview/fractusist/0.1.1/LICENSE | 21 ++ packages/preview/fractusist/0.1.1/README.md | 126 ++++++++ .../0.1.1/examples/dragon-curve-n12.png | Bin 0 -> 222340 bytes .../0.1.1/examples/dragon-curve-n12.typ | 18 ++ .../preview/fractusist/0.1.1/src/dragon.typ | 82 +++++ .../preview/fractusist/0.1.1/src/hilbert.typ | 143 +++++++++ .../preview/fractusist/0.1.1/src/koch.typ | 144 +++++++++ packages/preview/fractusist/0.1.1/src/lib.typ | 4 + .../fractusist/0.1.1/src/sierpinski.typ | 290 ++++++++++++++++++ .../preview/fractusist/0.1.1/src/util.typ | 111 +++++++ .../0.1.1/tests/test-dragon-curve.typ | 63 ++++ .../0.1.1/tests/test-hilbert-curve.typ | 45 +++ .../0.1.1/tests/test-koch-curve.typ | 38 +++ .../0.1.1/tests/test-koch-snowflake.typ | 33 ++ .../0.1.1/tests/test-peano-curve.typ | 33 ++ .../tests/test-sierpinski-arrowhead-curve.typ | 39 +++ .../0.1.1/tests/test-sierpinski-curve.typ | 39 +++ .../tests/test-sierpinski-square-curve.typ | 39 +++ .../0.1.1/tests/test-sierpinski-triangle.typ | 45 +++ packages/preview/fractusist/0.1.1/typst.toml | 13 + 20 files changed, 1326 insertions(+) create mode 100644 packages/preview/fractusist/0.1.1/LICENSE create mode 100644 packages/preview/fractusist/0.1.1/README.md create mode 100644 packages/preview/fractusist/0.1.1/examples/dragon-curve-n12.png create mode 100644 packages/preview/fractusist/0.1.1/examples/dragon-curve-n12.typ create mode 100644 packages/preview/fractusist/0.1.1/src/dragon.typ create mode 100644 packages/preview/fractusist/0.1.1/src/hilbert.typ create mode 100644 packages/preview/fractusist/0.1.1/src/koch.typ create mode 100644 packages/preview/fractusist/0.1.1/src/lib.typ create mode 100644 packages/preview/fractusist/0.1.1/src/sierpinski.typ create mode 100644 packages/preview/fractusist/0.1.1/src/util.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-dragon-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-hilbert-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-koch-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-koch-snowflake.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-peano-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-sierpinski-arrowhead-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-sierpinski-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-sierpinski-square-curve.typ create mode 100644 packages/preview/fractusist/0.1.1/tests/test-sierpinski-triangle.typ create mode 100644 packages/preview/fractusist/0.1.1/typst.toml diff --git a/packages/preview/fractusist/0.1.1/LICENSE b/packages/preview/fractusist/0.1.1/LICENSE new file mode 100644 index 000000000..e2ed64c29 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Guangxi Liu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/preview/fractusist/0.1.1/README.md b/packages/preview/fractusist/0.1.1/README.md new file mode 100644 index 000000000..33c665ece --- /dev/null +++ b/packages/preview/fractusist/0.1.1/README.md @@ -0,0 +1,126 @@ +# Fractusist + +Create a variety of wonderful fractals in Typst. + + +## Examples + +The example below creates a dragon curve of the 12th iteration with the `dragon-curve` function. + +![The rendered dragon curve](./examples/dragon-curve-n12.png) + +
+ Show code + + ```typ + #set page(width: auto, height: auto, margin: 0pt) + + #dragon-curve( + 12, + step-size: 6, + stroke-style: stroke( + paint: gradient.linear(..color.map.crest, angle: 45deg), + thickness: 3pt, + cap: "square" + ) + ) + ``` +
+ + +## Features + +- Use SVG backend for image rendering. +- Generate fractals using [L-system](https://en.wikipedia.org/wiki/L-system). +- The number of iterations, step size, fill and stroke styles, etc. of generated fractals could be customized. + + +## Usage + +Import the latest version of this package with: + +```typ +#import "@preview/fractusist:0.1.1": * +``` + +Each function generates a specific fractal. The input and output arguments of all functions have a similar style. Typical input arguments are as follows: + +- `n`: the number of iterations (**the valid range of values depends on the specific function**). +- _`step-size`_: step size (in pt). +- _`fill-style`_: fill style, can be `none` or color or gradient (**exists only when the curve is closed**). +- _`stroke-style`_: stroke style, can be `none` or color or gradient or stroke object. +- _`width`_: the width of the image. +- _`height`_: the height of the image. +- _`fit`_: how the image should adjust itself to a given area, "cover" / "contain" / "stretch". + +The content returned is the `image` element. + +For more codes with these functions see [tests](./tests). + + +## Reference + +### Dragon + +- `dragon-curve`: Generate dragon curve (n: range **[0, 16]**). + +```typ +#let dragon-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + + +### Hilbert + +- `hilbert-curve`: Generate 2D Hilbert curve. (n: range **[1, 8]**). + +```typ +#let hilbert-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + +- `peano-curve`: Generate 2D Peano curve (n: range **[1, 5]**). + +```typ +#let peano-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + + +### Koch + +- `koch-curve`: Generate Koch curve (n: range **[0, 6]**). + +```typ +#let koch-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + +- `koch-snowflake`: Generate Koch snowflake (n: range **[0, 6]**). + +```typ +#let koch-snowflake(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + + +### Sierpiński + +- `sierpinski-curve`: Generate classic Sierpiński curve (n: range **[0, 7]**). + +```typ +#let sierpinski-curve(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + +- `sierpinski-square-curve`: Generate Sierpiński square curve (n: range **[0, 7]**). + +```typ +#let sierpinski-square-curve(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + +- `sierpinski-arrowhead-curve`: Generate Sierpiński arrowhead curve (n: range **[0, 8]**). + +```typ +#let sierpinski-arrowhead-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` + +- `sierpinski-triangle`: Generate 2D Sierpiński triangle (n: range **[0, 6]**). + +```typ +#let sierpinski-triangle(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = {...} +``` diff --git a/packages/preview/fractusist/0.1.1/examples/dragon-curve-n12.png b/packages/preview/fractusist/0.1.1/examples/dragon-curve-n12.png new file mode 100644 index 0000000000000000000000000000000000000000..988e6a303d49ec55dd8b3b20144b8113eaed4f48 GIT binary patch literal 222340 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

3|R_q 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 fpO|L|FZ+IEk2P9* "X+YF+" +// "Y" -> "-FX-Y" +// angle: 90 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let dragon-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 16, message: "`n` should be in range [0, 16]") + assert(step-size > 0, message: "`step-size` should be positive") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "FX" + let rule-set = (X: "X+YF+", Y: "-FX-Y") + let dx = (step-size, 0, -step-size, 0) + let dy = (0, step-size, 0, -step-size) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace(regex("X|Y"), x => rule-set.at(x.text))} + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 3} + } else if c == "+" { + dir += 1 + if (dir == 4) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + + let tbl-x-min = (0, 0, 0, -2, -4, -5, -5, -5, -5, -5, -10, -42, -74, -85, -85, -85, -85) + let tbl-x-max = (0, 1, 1, 1, 1, 1, 2, 10, 18, 21, 21, 21, 21, 21, 42, 170, 298) + let tbl-y-min = (0, 0, 0, 0, -1, -5, -9, -10, -10, -10, -10, -10, -21, -85, -149, -170, -170) + let tbl-y-max = (0, 1, 2, 2, 2, 2, 2, 2, 5, 21, 37, 42, 42, 42, 42, 42, 85) + let margin = calc.max(5, stroke-width) + let x-min = tbl-x-min.at(n) * step-size + let x-max = tbl-x-max.at(n) * step-size + let y-min = tbl-y-min.at(n) * step-size + let y-max = tbl-y-max.at(n) * step-size + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), none, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} diff --git a/packages/preview/fractusist/0.1.1/src/hilbert.typ b/packages/preview/fractusist/0.1.1/src/hilbert.typ new file mode 100644 index 000000000..39754f9c8 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/src/hilbert.typ @@ -0,0 +1,143 @@ +//============================================================================== +// The Hilbert curve +// +// Public functions: +// hilbert-curve, peano-curve +//============================================================================== + + +#import "util.typ": gen-svg + + +//---------------------------------------------------------- +// Public functions +//---------------------------------------------------------- + +// Generate 2D Hilbert curve +// +// iterations: [1, 8] +// axiom: "W" +// rule set: +// "V" -> "-WF+VFV+FW-" +// "W" -> "+VF-WFW-FV+" +// angle: 90 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let hilbert-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 1 and n <= 8, message: "`n` should be in range [1, 8]") + assert(step-size > 0, message: "`step-size` should be positive") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "W" + let rule-set = (V: "-WF+VFV+FW-", W: "+VF-WFW-FV+") + let dx = (step-size, 0, -step-size, 0) + let dy = (0, step-size, 0, -step-size) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace(regex("V|W"), x => rule-set.at(x.text))} + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 3} + } else if c == "+" { + dir += 1 + if (dir == 4) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + + let margin = calc.max(5, stroke-width) + let x-min = 0 + let x-max = (calc.pow(2, n) - 1) * step-size + let y-min = 0 + let y-max = x-max + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), none, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} + + +// Generate 2D Peano curve (Hilbert II curve) +// +// iterations: [1, 5] +// axiom: "X" +// rule set: +// "X" -> "XFYFX+F+YFXFY-F-XFYFX" +// "Y" -> "YFXFY-F-XFYFX+F+YFXFY" +// angle: 90 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let peano-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 1 and n <= 5, message: "`n` should be in range [1, 5]") + assert(step-size > 0, message: "`step-size` should be positive") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "X" + let rule-set = (X: "XFYFX+F+YFXFY-F-XFYFX", Y: "YFXFY-F-XFYFX+F+YFXFY") + let dx = (step-size, 0, -step-size, 0) + let dy = (0, step-size, 0, -step-size) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace(regex("X|Y"), x => rule-set.at(x.text))} + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 3} + } else if c == "+" { + dir += 1 + if (dir == 4) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + + let margin = calc.max(5, stroke-width) + let x-min = 0 + let x-max = (calc.pow(3, n) - 1) * step-size + let y-min = 0 + let y-max = x-max + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), none, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} diff --git a/packages/preview/fractusist/0.1.1/src/koch.typ b/packages/preview/fractusist/0.1.1/src/koch.typ new file mode 100644 index 000000000..b3d4d040b --- /dev/null +++ b/packages/preview/fractusist/0.1.1/src/koch.typ @@ -0,0 +1,144 @@ +//============================================================================== +// The Koch curve +// +// Public functions: +// koch-curve, koch-snowflake +//============================================================================== + + +#import "util.typ": gen-svg + + +//---------------------------------------------------------- +// Public functions +//---------------------------------------------------------- + +// Generate Koch curve +// +// iterations: [0, 6] +// axiom: "F" +// rule set: +// "F" -> "F-F++F-F" +// angle: 60 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let koch-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 6, message: "`n` should be in range [0, 6]") + assert(step-size > 0, message: "`step-size` should be positive") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "F" + let rule-set = ("F": "F-F++F-F") + let dx = (step-size, step-size/2, -step-size/2, -step-size, -step-size/2, step-size/2) + let dy = (0, step-size/2*calc.sqrt(3), step-size/2*calc.sqrt(3), 0, -step-size/2*calc.sqrt(3), -step-size/2*calc.sqrt(3)) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace("F", rule-set.at("F"))} + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 5} + } else if c == "+" { + dir += 1 + if (dir == 6) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + + let margin = calc.max(5, stroke-width * 1.5) + let x-min = 0 + let x-max = calc.pow(3, n) * step-size + let y-min = -calc.pow(3, n - 1) * calc.sqrt(3)/2 * step-size + let y-max = 0 + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), none, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} + + +// Generate Koch snowflake +// +// iterations: [0, 6] +// axiom: "F++F++F" +// rule set: +// "F" -> "F-F++F-F" +// angle: 60 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// fill-style: fill style, can be none or color or gradient, optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let koch-snowflake(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 6, message: "`n` should be in range [0, 6]") + assert(step-size > 0, message: "`step-size` should be positive") + assert((fill-style == none) or (type(fill-style) == color) or (type(fill-style) == gradient and (repr(fill-style.kind()) == "linear" or repr(fill-style.kind()) == "radial")), message: "`fill-style` should be none / color / gradient.linear / gradient.radial") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "F++F++F" + let rule-set = ("F": "F-F++F-F") + let dx = (step-size, step-size/2, -step-size/2, -step-size, -step-size/2, step-size/2) + let dy = (0, step-size/2*calc.sqrt(3), step-size/2*calc.sqrt(3), 0, -step-size/2*calc.sqrt(3), -step-size/2*calc.sqrt(3)) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace("F", rule-set.at("F"))} + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 5} + } else if c == "+" { + dir += 1 + if (dir == 6) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + path-d += "Z" + + let margin = calc.max(5, stroke-width * 1.5) + let x-min = 0 + let x-max = calc.pow(3, n) * step-size + let y-min = -calc.pow(3, n - 1) * calc.sqrt(3)/2 * step-size + let y-max = calc.pow(3, n - 1) * calc.sqrt(3)*3/2 * step-size + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), fill-style, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} diff --git a/packages/preview/fractusist/0.1.1/src/lib.typ b/packages/preview/fractusist/0.1.1/src/lib.typ new file mode 100644 index 000000000..25d415c8f --- /dev/null +++ b/packages/preview/fractusist/0.1.1/src/lib.typ @@ -0,0 +1,4 @@ +#import "dragon.typ": dragon-curve +#import "hilbert.typ": hilbert-curve, peano-curve +#import "koch.typ": koch-curve, koch-snowflake +#import "sierpinski.typ": sierpinski-curve, sierpinski-square-curve, sierpinski-arrowhead-curve, sierpinski-triangle diff --git a/packages/preview/fractusist/0.1.1/src/sierpinski.typ b/packages/preview/fractusist/0.1.1/src/sierpinski.typ new file mode 100644 index 000000000..bdf944f52 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/src/sierpinski.typ @@ -0,0 +1,290 @@ +//============================================================================== +// The Sierpiński curve +// +// Public functions: +// sierpinski-curve, sierpinski-square-curve +// sierpinski-arrowhead-curve +// sierpinski-triangle +//============================================================================== + + +#import "util.typ": gen-svg + + +//---------------------------------------------------------- +// Public functions +//---------------------------------------------------------- + +// Generate classic Sierpiński curve +// +// iterations: [0, 7] +// axiom: "F--XF--F--XF" +// rule set: +// "X" -> "XF+G+XF--F--XF+G+X" +// angle: 45 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// fill-style: fill style, can be none or color or gradient, optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let sierpinski-curve(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 7, message: "`n` should be in range [0, 7]") + assert(step-size > 0, message: "`step-size` should be positive") + assert((fill-style == none) or (type(fill-style) == color) or (type(fill-style) == gradient and (repr(fill-style.kind()) == "linear" or repr(fill-style.kind()) == "radial")), message: "`fill-style` should be none / color / gradient.linear / gradient.radial") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "F--XF--F--XF" + let rule-set = ("X": "XF+G+XF--F--XF+G+X") + let fdx = (step-size, step-size/2*calc.sqrt(2), 0, -step-size/2*calc.sqrt(2), -step-size, -step-size/2*calc.sqrt(2), 0, step-size/2*calc.sqrt(2)) + let fdy = (0, step-size/2*calc.sqrt(2), step-size, step-size/2*calc.sqrt(2), 0, -step-size/2*calc.sqrt(2), -step-size, -step-size/2*calc.sqrt(2)) + let gdx = (step-size*calc.sqrt(2), step-size, 0, -step-size, -step-size*calc.sqrt(2), -step-size, 0, step-size) + let gdy = (0, step-size, step-size*calc.sqrt(2), step-size, 0, -step-size, -step-size*calc.sqrt(2), -step-size) + let fdx-str = fdx.map(i => repr(i)) + let fdy-str = fdy.map(i => repr(i)) + let gdx-str = gdx.map(i => repr(i)) + let gdy-str = gdy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace("X", rule-set.at("X"))} + + let dir = 7 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 7} + } else if c == "+" { + dir += 1 + if (dir == 8) {dir = 0} + } else if c == "F" { + path-d += "l" + fdx-str.at(dir) + " " + fdy-str.at(dir) + " " + } else if c == "G" { + path-d += "l" + gdx-str.at(dir) + " " + gdy-str.at(dir) + " " + } + } + path-d += "Z" + + let margin = calc.max(5, stroke-width * 1.5) + let x-min = (3/2 - calc.pow(2, n + 1)) * calc.sqrt(2) * step-size + let x-max = step-size / 2 * calc.sqrt(2) + let y-min = (1 - calc.pow(2, n + 1)) * calc.sqrt(2) * step-size + let y-max = 0 + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), fill-style, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} + + +// Generate Sierpiński square curve +// +// iterations: [0, 7] +// axiom: "F+XF+F+XF" +// rule set: +// "X" -> "XF-F+F-XF+F+XF-F+F-X" +// angle: 90 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// fill-style: fill style, can be none or color or gradient, optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let sierpinski-square-curve(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 7, message: "`n` should be in range [0, 7]") + assert(step-size > 0, message: "`step-size` should be positive") + assert((fill-style == none) or (type(fill-style) == color) or (type(fill-style) == gradient and (repr(fill-style.kind()) == "linear" or repr(fill-style.kind()) == "radial")), message: "`fill-style` should be none / color / gradient.linear / gradient.radial") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "F+XF+F+XF" + let rule-set = ("X": "XF-F+F-XF+F+XF-F+F-X") + let dx = (step-size, 0, -step-size, 0) + let dy = (0, step-size, 0, -step-size) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace("X", rule-set.at("X"))} + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 3} + } else if c == "+" { + dir += 1 + if (dir == 4) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + path-d += "Z" + + let margin = calc.max(5, stroke-width) + let x-min = (2 - calc.pow(2, n + 1)) * step-size + let x-max = (calc.pow(2, n + 1) - 1) * step-size + let y-min = 0 + let y-max = (calc.pow(2, n + 2) - 3) * step-size + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), fill-style, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} + + +// Generate Sierpiński arrowhead curve +// +// iterations: [0, 8] +// axiom: "XF" +// rule set: +// "X" -> "YF+XF+Y" +// "Y" -> "XF-YF-X" +// angle: 60 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let sierpinski-arrowhead-curve(n, step-size: 10, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 8, message: "`n` should be in range [0, 8]") + assert(step-size > 0, message: "`step-size` should be positive") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "XF" + let rule-set = (X: "YF+XF+Y", Y: "XF-YF-X") + let dx = (step-size, step-size/2, -step-size/2, -step-size, -step-size/2, step-size/2) + let dy = (0, step-size/2*calc.sqrt(3), step-size/2*calc.sqrt(3), 0, -step-size/2*calc.sqrt(3), -step-size/2*calc.sqrt(3)) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace(regex("X|Y"), x => rule-set.at(x.text))} + + + let dir = if calc.even(n) {0} else {5} + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 5} + } else if c == "+" { + dir += 1 + if (dir == 6) {dir = 0} + } else if c == "F" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + + let margin = calc.max(5, stroke-width * 1.5) + let x-min = 0 + let x-max = calc.pow(2, n) * step-size + let y-min = (1 - calc.pow(2, n)) * calc.sqrt(3)/2 * step-size + let y-max = 0 + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), none, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} + + +// Generate 2D Sierpiński triangle +// +// iterations: [0, 6] +// axiom: "F-G-G" +// rule set: +// "F" -> "F-G+F+G-F" +// "G" -> "GG" +// angle: 120 deg +// +// Arguments: +// n: the number of iterations +// step-size: step size (in pt), optional +// fill-style: fill style, can be none or color or gradient, optional +// stroke-style: stroke style, can be none or color or gradient or stroke object, optional +// width: the width of the image, optional +// height: the height of the image, optional +// fit: how the image should adjust itself to a given area, "cover" / "contain" / "stretch", optional +// +// Returns: +// content: generated vector graphic +#let sierpinski-triangle(n, step-size: 10, fill-style: none, stroke-style: black + 1pt, width: auto, height: auto, fit: "cover") = { + assert(type(n) == int and n >= 0 and n <= 6, message: "`n` should be in range [0, 6]") + assert(step-size > 0, message: "`step-size` should be positive") + assert((fill-style == none) or (type(fill-style) == color) or (type(fill-style) == gradient and (repr(fill-style.kind()) == "linear" or repr(fill-style.kind()) == "radial")), message: "`fill-style` should be none / color / gradient.linear / gradient.radial") + + if stroke-style != none {stroke-style = stroke(stroke-style)} + let stroke-width = if (stroke-style == none) {0} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + + let axiom = "F-G-G" + let rule-set = ("F": "F-G+F+G-F", "G": "GG") + let dx = (step-size, -step-size/2, -step-size/2) + let dy = (0, step-size/2*calc.sqrt(3), -step-size/2*calc.sqrt(3)) + let dx-str = dx.map(i => repr(i)) + let dy-str = dy.map(i => repr(i)) + + let s = axiom + for i in range(n) {s = s.replace(regex("F|G"), x => rule-set.at(x.text))} + + + let dir = 0 + let path-d = "M0 0 " + for c in s { + if c == "-" { + dir -= 1 + if dir < 0 {dir = 2} + } else if c == "+" { + dir += 1 + if (dir == 3) {dir = 0} + } else if c == "F" or c == "G" { + path-d += "l" + dx-str.at(dir) + " " + dy-str.at(dir) + " " + } + } + path-d += "Z" + + let margin = calc.max(5, stroke-width) + let x-min = 0 + let x-max = calc.pow(2, n) * step-size + let y-min = -calc.pow(2, n - 1) * calc.sqrt(3) * step-size + let y-max = 0 + x-min = calc.floor(x-min - margin) + x-max = calc.ceil(x-max + margin) + y-min = calc.floor(y-min - margin) + y-max = calc.ceil(y-max + margin) + + let svg-code = gen-svg(path-d, (x-min, x-max, y-min, y-max), fill-style, stroke-style) + return image(bytes(svg-code), width: width, height: height, fit: fit) +} diff --git a/packages/preview/fractusist/0.1.1/src/util.typ b/packages/preview/fractusist/0.1.1/src/util.typ new file mode 100644 index 000000000..47c8464cc --- /dev/null +++ b/packages/preview/fractusist/0.1.1/src/util.typ @@ -0,0 +1,111 @@ +//============================================================================== +// Utilities for SVG code generation +//============================================================================== + + +// SVG template strings +#let SVG-HEADER = "\n" +#let SVG-TAIL = "\n" +#let SVG-DEFS = "\nDEFS\n" +#let SVG-PATH = "\n" + + +// Generate linear gradient code +#let gen-svg-lineargradient(grad, id) = { + let t = calc.rem-euclid(grad.angle().deg(), 360) + let t2 = calc.rem-euclid(t, 90) + if t2 > 45 {t2 = 90 - t2} + let k = 0.5 / calc.cos(t2 * 1deg) + let x1 = 0.5 - k * calc.cos(t * 1deg) + let y1 = 0.5 - k * calc.sin(t * 1deg) + let x2 = 1 - x1 + let y2 = 1 - y1 + + let s = "".replace("ID", id).replace("X1", repr(x1)).replace("Y1", repr(y1)).replace("X2", repr(x2)).replace("Y2", repr(y2)) + for (c, r) in grad.stops() { + s += "".replace("RATIO", repr(r)).replace("COLOR", c.to-hex()) + } + s += "\n" + return s +} + + +// Generate radial gradient code +#let gen-svg-radialgradient(grad, id) = { + let cx = 0.5 + let cy = 0.5 + let r = 0.5 + let fx = 0.5 + let fy = 0.5 + + let cxy-match = repr(grad).match(regex("[^-]center:\s\(([\.\d]*)%,\s([\.\d]*)%\)")) + if cxy-match != none { + cx = float(cxy-match.captures.at(0)) / 100 + cy = float(cxy-match.captures.at(1)) / 100 + } + + let r-match = repr(grad).match(regex("[^-]radius:\s([\.\d]*)%")) + if r-match != none { + r = float(r-match.captures.at(0)) / 100 + } + + let fxy-match = repr(grad).match(regex("focal-center:\s\(([\.\d]*)%,\s([\.\d]*)%\)")) + if fxy-match != none { + fx = float(fxy-match.captures.at(0)) / 100 + fy = float(fxy-match.captures.at(1)) / 100 + } + + let s = "".replace("ID", id).replace("CX", repr(cx)).replace("CY", repr(cy)).replace("R", repr(r)).replace("FX", repr(fx)).replace("FY", repr(fy)) + for (c, r) in grad.stops() { + s += "".replace("RATIO", repr(r)).replace("COLOR", c.to-hex()) + } + s += "\n" + return s +} + + +// Generate full code +#let gen-svg(path-d, bbox, fill-style, stroke-style) = { + let stroke-color = if (stroke-style == none) {none} else if (stroke-style.paint == auto) {black} else {stroke-style.paint} + let stroke-width = if (stroke-style == none) {none} else if (stroke-style.thickness == auto) {1} else {calc.abs(stroke-style.thickness.pt())} + let stroke-linecap = if (stroke-style == none or stroke-style.cap == auto) {none} else {stroke-style.cap} + let stroke-linejoin = if (stroke-style == none or stroke-style.join == auto) {none} else {stroke-style.join} + let stroke-miterlimit = if (stroke-style == none or stroke-style.miter-limit == auto) {none} else {stroke-style.miter-limit} + + let fill-color-str = "none" + let stroke-color-str = "none" + let grad-str = "" + + if type(fill-style) == color { + fill-color-str = fill-style.to-hex() + } else if type(fill-style) == gradient and repr(fill-style.kind()) == "linear" { + grad-str += gen-svg-lineargradient(fill-style, "GradFill") + fill-color-str = "url(#GradFill)" + } else if type(fill-style) == gradient and repr(fill-style.kind()) == "radial" { + grad-str += gen-svg-radialgradient(fill-style, "GradFill") + fill-color-str = "url(#GradFill)" + } + + if type(stroke-color) == color { + stroke-color-str = stroke-color.to-hex() + } else if type(stroke-color) == gradient and repr(stroke-color.kind()) == "linear" { + grad-str += gen-svg-lineargradient(stroke-color, "GradStroke") + stroke-color-str = "url(#GradStroke)" + } else if type(stroke-color) == gradient and repr(stroke-color.kind()) == "radial" { + grad-str += gen-svg-radialgradient(stroke-color, "GradStroke") + stroke-color-str = "url(#GradStroke)" + } + + let path-style = "fill:" + fill-color-str + ";stroke:" + stroke-color-str + ";stroke-width:" + repr(stroke-width) + if stroke-linecap != none {path-style += ";stroke-linecap:" + stroke-linecap} + if stroke-linejoin != none {path-style += ";stroke-linejoin:" + stroke-linejoin} + if stroke-miterlimit != none {path-style += ";stroke-miterlimit:" + repr(stroke-linejoin)} + + let path-transform = "translate" + repr((-bbox.at(0), -bbox.at(2))) + + let s = SVG-HEADER.replace("WIDTH", repr(bbox.at(1) - bbox.at(0))).replace("HEIGHT", repr(bbox.at(3) - bbox.at(2))) + if grad-str != "" {s += SVG-DEFS.replace("DEFS", grad-str)} + s += SVG-PATH.replace("STYLE", path-style).replace("TRANSFORM", path-transform).replace("PATHD", path-d) + s += SVG-TAIL + return s +} diff --git a/packages/preview/fractusist/0.1.1/tests/test-dragon-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-dragon-curve.typ new file mode 100644 index 000000000..337bd2891 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-dragon-curve.typ @@ -0,0 +1,63 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #dragon-curve(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #dragon-curve(2, step-size: 20, stroke-style: stroke(paint: red, thickness: 2pt, cap: "square")) +] + + += n = 3 +#align(center)[ + #dragon-curve(3, step-size: 20, stroke-style: stroke(paint: orange, thickness: 4pt, cap: "square")) +] + + += n = 4 +#align(center)[ + #dragon-curve(4, step-size: 20, stroke-style: stroke(paint: green, thickness: 6pt, cap: "square")) +] + + += n = 5 +#align(center)[ + #dragon-curve(5, step-size: 16, stroke-style: stroke(paint: blue, thickness: 8pt, cap: "round", join: "round")) +] + + += n = 6 +#align(center)[ + #dragon-curve(6, step-size: 16, stroke-style: stroke(paint: purple, thickness: 8pt, cap: "square")) +] +#pagebreak(weak: true) + + += n = 7 +#align(center)[ + #dragon-curve(7, step-size: 10, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 2pt, cap: "square")) +] + + += n = 8 +#align(center)[ + #dragon-curve(8, step-size: 10, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 3pt, cap: "square")) +] + + += n = 9 +#align(center)[ + #dragon-curve(9, step-size: 10, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 4pt, cap: "square")) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-hilbert-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-hilbert-curve.typ new file mode 100644 index 000000000..94f0e5194 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-hilbert-curve.typ @@ -0,0 +1,45 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #hilbert-curve(1, step-size: 50) +] + + += n = 2 +#align(center)[ + #hilbert-curve(2, step-size: 30, stroke-style: blue) +] + + += n = 3 +#align(center)[ + #hilbert-curve(3, step-size: 30, stroke-style: red + 4pt) +] + + += n = 4 +#align(center)[ + #hilbert-curve(4, step-size: 15, stroke-style: stroke(paint: gray, thickness: 5pt, cap: "round", join: "round")) +] +#pagebreak(weak: true) + + += n = 5 +#align(center)[ + #hilbert-curve(5, step-size: 8, stroke-style: stroke(paint: purple, thickness: 2pt, cap: "square")) +] + + += n = 6 +#align(center)[ + #hilbert-curve(6, step-size: 6, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 4pt, cap: "square")) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-koch-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-koch-curve.typ new file mode 100644 index 000000000..350366bea --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-koch-curve.typ @@ -0,0 +1,38 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #koch-curve(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #koch-curve(2, step-size: 20, stroke-style: red + 2pt) +] + + += n = 3 +#align(center)[ + #koch-curve(3, step-size: 10, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 4pt)) +] + + += n = 4 +#align(center)[ + #koch-curve(4, step-size: 5, stroke-style: stroke(paint: gradient.linear(..color.map.rainbow, angle: 45deg), thickness: 2pt)) +] + + += n = 5 +#align(center)[ + #koch-curve(5, step-size: 2, stroke-style: blue) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-koch-snowflake.typ b/packages/preview/fractusist/0.1.1/tests/test-koch-snowflake.typ new file mode 100644 index 000000000..145909f3e --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-koch-snowflake.typ @@ -0,0 +1,33 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #koch-snowflake(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #koch-snowflake(2, step-size: 20, fill-style: gray, stroke-style: none) +] + + += n = 3 +#align(center)[ + #koch-snowflake(3, step-size: 8, fill-style: silver, stroke-style: orange + 3pt) +] +#pagebreak(weak: true) + + += n = 4 +#align(center)[ + #koch-snowflake(4, step-size: 5, fill-style: gradient.radial((orange, 0%), (silver, 100%), focal-center: (30%, 30%)), stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 2pt)) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-peano-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-peano-curve.typ new file mode 100644 index 000000000..cd9c1ced6 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-peano-curve.typ @@ -0,0 +1,33 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #peano-curve(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #peano-curve(2, step-size: 10, stroke-style: blue + 4pt) +] + + += n = 3 +#align(center)[ + #peano-curve(4, step-size: 5, stroke-style: stroke(paint: gray, thickness: 2pt, cap: "square")) +] +#pagebreak(weak: true) + + += n = 4 +#align(center)[ + #peano-curve(4, step-size: 6, stroke-style: stroke(paint: gradient.radial(..color.map.crest), thickness: 4pt, cap: "square")) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-sierpinski-arrowhead-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-arrowhead-curve.typ new file mode 100644 index 000000000..d80983b1d --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-arrowhead-curve.typ @@ -0,0 +1,39 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #sierpinski-arrowhead-curve(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #sierpinski-arrowhead-curve(2, step-size: 20, stroke-style: red + 2pt) +] + + += n = 3 +#align(center)[ + #sierpinski-arrowhead-curve(3, step-size: 20, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 4pt)) +] + + += n = 4 +#align(center)[ + #sierpinski-arrowhead-curve(4, step-size: 20, stroke-style: stroke(paint: gradient.linear(..color.map.rainbow, angle: 45deg), thickness: 10pt, cap: "round", join: "round")) +] +#pagebreak(weak: true) + + += n = 5 +#align(center)[ + #sierpinski-arrowhead-curve(5, step-size: 10, stroke-style: stroke(paint: purple, thickness: 2pt, cap: "square")) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-sierpinski-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-curve.typ new file mode 100644 index 000000000..c03cabcb3 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-curve.typ @@ -0,0 +1,39 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #sierpinski-curve(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #sierpinski-curve(2, step-size: 20, fill-style: gray, stroke-style: none) +] + + += n = 3 +#align(center)[ + #sierpinski-curve(3, step-size: 10, fill-style: silver, stroke-style: stroke(paint: orange, thickness: 3pt, cap: "round", join: "round")) +] +#pagebreak(weak: true) + + += n = 4 +#align(center)[ + #sierpinski-curve(4, step-size: 6, fill-style: gradient.radial((orange, 0%), (silver, 100%), focal-center: (30%, 30%)), stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 2pt)) +] + + += n = 5 +#align(center)[ + #sierpinski-curve(5, step-size: 4, fill-style: gradient.linear(..color.map.crest, angle: 45deg), stroke-style: none) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-sierpinski-square-curve.typ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-square-curve.typ new file mode 100644 index 000000000..5b0c64319 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-square-curve.typ @@ -0,0 +1,39 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #sierpinski-square-curve(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #sierpinski-square-curve(2, step-size: 15, fill-style: gray, stroke-style: none) +] + + += n = 3 +#align(center)[ + #sierpinski-square-curve(3, step-size: 8, fill-style: silver, stroke-style: stroke(paint: orange, thickness: 3pt, cap: "round", join: "round")) +] +#pagebreak(weak: true) + + += n = 4 +#align(center)[ + #sierpinski-square-curve(4, step-size: 4, fill-style: gradient.radial((orange, 0%), (silver, 100%), focal-center: (30%, 30%)), stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 2pt)) +] + + += n = 5 +#align(center)[ + #sierpinski-square-curve(5, step-size: 3, fill-style: gradient.linear(..color.map.crest, angle: 45deg), stroke-style: none) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/tests/test-sierpinski-triangle.typ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-triangle.typ new file mode 100644 index 000000000..172e637b2 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/tests/test-sierpinski-triangle.typ @@ -0,0 +1,45 @@ +#set document(date: none) + + +#import "/src/lib.typ": * + + +#set page(margin: 1cm) + + += n = 1 +#align(center)[ + #sierpinski-triangle(1, step-size: 40) +] + + += n = 2 +#align(center)[ + #sierpinski-triangle(2, step-size: 30, fill-style: gray, stroke-style: none) +] + + += n = 3 +#align(center)[ + #sierpinski-triangle(3, step-size: 20, fill-style: none, stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 4pt, join: "bevel")) +] + + += n = 4 +#align(center)[ + #sierpinski-triangle(4, step-size: 20, fill-style: gradient.radial((orange, 0%), (silver, 100%), focal-center: (30%, 30%)), stroke-style: stroke(paint: gradient.linear(..color.map.crest, angle: 45deg), thickness: 2pt, join: "bevel")) +] +#pagebreak(weak: true) + + += n = 5 +#align(center)[ + #sierpinski-triangle(5, step-size: 10, fill-style: none, stroke-style: stroke(paint: purple, thickness: 2pt, join: "bevel")) +] + + += n = 6 +#align(center)[ + #sierpinski-triangle(6, step-size: 6, fill-style: gradient.linear(..color.map.crest, angle: 45deg), stroke-style: none) +] +#pagebreak(weak: true) diff --git a/packages/preview/fractusist/0.1.1/typst.toml b/packages/preview/fractusist/0.1.1/typst.toml new file mode 100644 index 000000000..8fae88b76 --- /dev/null +++ b/packages/preview/fractusist/0.1.1/typst.toml @@ -0,0 +1,13 @@ +[package] +name = "fractusist" +version = "0.1.1" +entrypoint = "src/lib.typ" +authors = ["Guangxi Liu "] +license = "MIT" +description = "Create a variety of wonderful fractals in Typst." +repository = "https://github.com/liuguangxi/fractusist" +keywords = ["fractal", "L-system", "dragon", "Hilbert", "Koch", "Sierpinski"] +categories = ["components", "visualization"] +disciplines = ["computer-science", "mathematics"] +compiler = "0.13.0" +exclude = ["examples", "tests"]