概要
ということなのでTypstでマンデルブロ集合を描画します.CeTZをつかいますが,といってもCeTZを使うのは座標の点で描画するためだけです.それ以外は基本機能ですべて計算できます.
マンデルブロ集合には複素数平面上の集合なので,複素数を使う必要があります.複素数を扱うパッケージもありますが.ここでは2要素の array で十分なのでそれで表現します.
マンデルブロ集合そのものの解説はウェブ上にたくさんありますのでそちらをご覧ください.
コード
#import "@preview/cetz:0.3.1"
#set page(width:auto,height:auto, margin:0pt)
//遷移関数の定義
#let Md(z, c) = {
let real = z.at(0)
let img = z.at(1)
return (calc.pow(real,2) - calc.pow(img, 2) + c.at(0), 2*real*img+c.at(1))
}
//複素数の絶対値(の二乗)の計算
#let c_abs(z) = {
let real = z.at(0)
let img = z.at(1)
return calc.pow(real,2) + calc.pow(img, 2)
}
//マンデルブロ集合を計算する.発散速度に応じて色分けをするために何回で絶対値の二乗が4を越えたかを出力する.上限に達したら255を返す.
#let Mandelbrot(c) = {
let z = (0,0)
let bound = 50
let i = 1
for i in range(bound) {
z = Md(z,c)
if c_abs(z)>4 {return calc.min(i * 5, 255); break}
}
return 255
}
//CeTZで描画.円だと隙間があるので正方形で描画
#cetz.canvas(length:2cm, {
import cetz.draw: *
let grid = 355
for i in range(grid) {
for j in range(grid) {
let x = 1 - 3*i/(grid)
let y = 1 - 2*j/(grid)
let M = Mandelbrot((x,y))
rect((x,y),(x+ 0.02,y + 0.02), fill:color.map.rainbow.at(M), stroke:none)
}
}
})
実行結果
感想
コンパイル時間は2min 28.84 s でした.TypstはTeXに比べて速いとは言いますが,こういうことをさせるには(当然と言うか)向いていませんね.