129 lines
2.9 KiB
Plaintext
129 lines
2.9 KiB
Plaintext
|
#include calc
|
||
|
|
||
|
#let bold(cnt) = text(weight: "bold", cnt)
|
||
|
#let MyStyle(doc) = [
|
||
|
#set page(margin: (left:10mm, right: 10mm, top: 5mm, bottom: 5mm))
|
||
|
#set text(size: 15pt, hyphenate: false)
|
||
|
#doc
|
||
|
]
|
||
|
|
||
|
#let rnd-next-seed(seed) = {
|
||
|
let a = 1664525
|
||
|
let c = 1013904223
|
||
|
let m = 4294967296
|
||
|
return calc.rem(a * seed + c, m)
|
||
|
}
|
||
|
|
||
|
#let rnd-number-in-range(seed, L, R) = {
|
||
|
if L >= R{
|
||
|
panic("This is wrong")
|
||
|
}
|
||
|
let S = R - L;
|
||
|
let seed2 = rnd-next-seed(seed)
|
||
|
(seed2, L + calc.rem(seed2, S) + L)
|
||
|
}
|
||
|
|
||
|
#let rnd-float(seed) = {
|
||
|
let seed2 = rnd-next-seed(seed)
|
||
|
let F = float(calc.rem(seed2, 65536)) / (65536 - 1)
|
||
|
(seed2, F)
|
||
|
}
|
||
|
|
||
|
#let rnd-vec2(seed, amplitude) = {
|
||
|
let (seed, F1) = rnd-float(seed)
|
||
|
let (seed, F2) = rnd-float(seed)
|
||
|
(seed, (F1 * amplitude, F2 * amplitude))
|
||
|
}
|
||
|
|
||
|
#let add-vec2(A, B) = (A.at(0) + B.at(0), A.at(1) + B.at(1))
|
||
|
|
||
|
#let float-to-edges(x) = if (x < 0.5) {calc.pow(x, 2)} else {1 - calc.pow(1 - x, 2)}
|
||
|
|
||
|
#let greenSunEffect(body) = text(weight: "bold", fill: green, font: "Pixeboy", body)
|
||
|
|
||
|
|
||
|
#let genLightningRoot(width, height, seed) = {
|
||
|
let roots = ()
|
||
|
let kb = 1
|
||
|
let spb = 6
|
||
|
let bpb = spb * 3
|
||
|
let i = kb * 1pt
|
||
|
let n = 0
|
||
|
while i + kb*1pt < width{
|
||
|
if (i + (bpb + spb + kb)*1pt > width or n > 1000){
|
||
|
i = width - kb*1pt
|
||
|
}
|
||
|
|
||
|
let y_RND = 0
|
||
|
(seed, y_RND) = rnd-float(seed)
|
||
|
let y = (float-to-edges(y_RND) * 0.8 + 0.1) * height
|
||
|
|
||
|
roots.push((i, y))
|
||
|
|
||
|
let x_RND = 0
|
||
|
(seed, x_RND) = rnd-number-in-range(seed, spb, bpb)
|
||
|
i += (x_RND * 1pt)
|
||
|
n += 1
|
||
|
}
|
||
|
(seed, roots)
|
||
|
}
|
||
|
|
||
|
#let genLightningSpark(start, amplitude, seed, is-g) = {
|
||
|
let sparks = 0
|
||
|
if (is-g) {
|
||
|
sparks = 2
|
||
|
} else {
|
||
|
let td_RND;
|
||
|
(seed, td_RND) = rnd-number-in-range(seed, 1, 9)
|
||
|
if (7 <= td_RND and td_RND <= 8){
|
||
|
sparks = 1
|
||
|
} else if (td_RND == 9){
|
||
|
sparks = 2
|
||
|
}
|
||
|
}
|
||
|
let res = ()
|
||
|
for I in range(0, sparks){
|
||
|
let curP = start
|
||
|
let one_line = (start,)
|
||
|
for j in range(0, 2){
|
||
|
let step;
|
||
|
(seed, step) = rnd-vec2(seed, amplitude)
|
||
|
curP = add-vec2(curP, step)
|
||
|
one_line.push(curP)
|
||
|
}
|
||
|
res.push(one_line)
|
||
|
}
|
||
|
(seed, res)
|
||
|
}
|
||
|
|
||
|
// Returns array of paths
|
||
|
#let genLightning(width, height, seed) = {
|
||
|
let (seed, root) = genLightningRoot(width, height, seed)
|
||
|
let paths = (root,)
|
||
|
let N = root.len()
|
||
|
for i in range(0, N){
|
||
|
let start = root.at(i)
|
||
|
let is-g = ((i == 0) or (i + 1 == N))
|
||
|
let amplitude = if (is-g) {height / 3} else {height / 2}
|
||
|
let new_lines
|
||
|
(seed, new_lines) = genLightningSpark(start, amplitude, seed, is-g)
|
||
|
for new_line in new_lines {
|
||
|
paths.push(new_line)
|
||
|
}
|
||
|
}
|
||
|
paths
|
||
|
}
|
||
|
|
||
|
#let lightningBackground(body, seed) = context {
|
||
|
let dim = measure(body)
|
||
|
let points = genLightning(dim.width, dim.height, seed)
|
||
|
// return points
|
||
|
box(inset:0pt, outset:0pt)[
|
||
|
#for lpath in points{
|
||
|
place(top+left, dx: 0pt, dy: 0pt, path(stroke: yellow+1pt, ..lpath))
|
||
|
}
|
||
|
#body
|
||
|
]
|
||
|
}
|
||
|
|
||
|
#let sparkingGreenSunEffect(seed, body) = lightningBackground(greenSunEffect(body), seed)
|