ある図形の変形を繰り返した結果できる図形があります。
たとえば、
(図1)
のような線分を
(図2)
のような数個の線分に
変形する操作を繰り返すことによって、
(図3)
のような図形を描くことができます。
ここで紹介するものは、このような図形を描画するための言語です。
この言語 Fractal# では、 図形の情報の集合の間の変換を合成することができます。 図形の情報は、図の各(有向)線分の情報です。 図形が描画される平面を複素平面と考え、 始点が a、終点が a + b である線分を (a, b) と表します。 (0, 1) を単位線分と呼びます。 ある線分 (a, b) は単位線分 (0, 1) をその線分に写す変換と考えることができます。 線分 (a, b) に対応する変換を t(a, b) とすると、 変換 t(a, b) は線分 (c, d) を (a + bc, bd) に写す変換となります。 このような変換全体の集合を T とします。 集合 T の二つの元 t, s に対して、変換 t の結果に対して変換 s を適用した 結果を作る変換(変換の合成)を Fractal# では t & s と書きます。 集合 T の元 t に対して、「t の固定化」!t を考えます。 集合 T の元と「固定化された元」全体の集合を T' とします。すなわち
T' = { t, !t | t∈T }
と定義します。
固定化された元は演算 & によって変化しないとして、
集合 T' の二つの元 t', s' に対して、t' & s' を定義します。
t & !s = !(t & s),
!t & s = !t,
!t & !s = !t
とします。
集合 T' の二つの部分集合 x、y に対して、
x の元であるすべての変換 t と
y の元であるすべての変換 s とからできる t & s 全体の集合を x & y とします。すなわち
x & y = { t & s | t∈x, s∈y }
と定義します。
また、x と y の和集合を x | y と書きます。
たとえば、
(図4)
のような線分を、
(図5)
のような数個の線分に変形する変換は、
線分 L から線分 A、B、C、D への変換をそれぞれ a、b、c、d とすると、
Fractalでは図4から図5への変換は、a | b | c | d と表すことができます。
また、a | b | c | d を e とすると、図4から
(図6)
への変換は、
e & e & e & e と表すことができます。
定義; 定義; ... 定義; 式
最後の式は、この式を繰り返すことを表します。
これを「繰り返し式」と呼びます(後述)。
「定義」は変数の定義
var 変数名 = 式
または関数の定義
var 関数名 = (変数名, 変数名, ... , 変数名) => 式
です。
//から行の終わりまではコメントです。
(式 二項演算子 式) (単項演算子 式) (式 ? 式 : 式) 関数名(式, 式, … , 式) 関数名(式..式) (式 ^ 式)(式) (式)
数値は複素数とします。これは複素平面上の点を表します。 数値全体の集合を N で表します。 真理値(真または偽)全体の集合を B で表します。 T' を上で定義した固定化されていないかまたは固定化された変換(線分)全体の集合とし、 L を T' の部分集合全体の集合とします。
| 演算子 | 型 | 意味 |
|---|---|---|
| + | N×N→N | 加算 |
| L×N→N | 加算(線分の移動)、(a, b) + c = (a + c, b) | |
| - | N×N→N | 減算 |
| L×N→N | 減算(線分の移動)、(a, b) - c = (a - c, b) | |
| * | N×N→N | 乗算 |
| L×N→N | 乗算(線分の長さと向きの変更)、(a, b) * c = (a, bc) | |
| / | N×N→N | 除算 |
| L×N→N | 除算(線分の長さと向きの変更)、(a, b) / c = (a, b/c) | |
| ^ | N×N→N | 累乗 |
| L×N→L | 変換の繰り返し、t ^ n = t & t & … & t (n個) | |
| (L→L)×N→(L→L) | 変換の繰り返し | |
| == | N×N→B | 等しい |
| != | N×N→B | 等しくない |
| < | N×N→B | 小さい |
| <= | N×N→B | 小さいか等しい |
| > | N×N→B | 大きい |
| >= | N×N→B | 大きいか等しい |
| 演算子 | 型 | 意味 |
|---|---|---|
| - | N→N | 符号を変える |
| ~ | N→N | 角度(度)を複素数に変換 |
| ! | L→L | 固定化 |
式1は真理値で、式1を評価した結果が真のとき式2を評価してその値がこの式の値となり、 偽のとき式3を評価してその値がこの式の値となります。
関数を評価します。「(式, 式, ... , 式)」の部分は関数の引数です。関数名は「定義」の部分で定義された「ユーザー定義関数」か、定義しなくても使える「システム標準関数」です。
上記の関数で、引数の個数が1個で、N から L への関数であるとき、この形式を使うことができます。 関数を f、式1の値を m、式2の値を n とすると、f(式1..式2) の値は f(m) | f(m+1) | … | f(n-1) となります。
上記の関数で、引数の個数が1個で、式1の値が L から L への関数、式2の値が数値であるとき、この形式を使うことができます。 式1の値を f、式2の値を n とすると、(式1 ^ 式2)(式3)の値は f を n 回繰り返した f(f(…(f(式3の値))…)) となります。
次のものがあります。 実数の関数もあります(実数を R で表します)。 基本的には C# で標準的に使えるものの中から JavaScript で簡単に実装できるものとしています。
| 名前 | 型 | 意味 |
|---|---|---|
| sin | N→N | 正弦関数 |
| cos | N→N | 余弦関数 |
| tan | N→N | 正接関数 |
| sinh | N→N | 双曲線正弦関数 |
| cosh | N→N | 双曲線余弦関数 |
| tanh | N→N | 双曲線正接関数 |
| acos | N→N | 逆余弦関数 |
| asin | N→N | 逆正弦関数 |
| atan | N→N | 逆正接関数 |
| asinh | R→R | 逆双曲線正弦関数 |
| acosh | R→R | 逆双曲線余弦関数 |
| atanh | R→R | 逆双曲線正接関数 |
| exp | N→N | 指数関数 |
| log | N→N | 対数関数 |
| log10 | N→N | 底 10 の対数関数 |
| log2 | N→N | 底 2 の対数関数 |
| sqrt | N→N | 平方根 |
| cbrt | N→N | 立方根 |
| abs | N→N | 絶対値 |
| sign | R→R | 符号を示す数値(正のとき1、0のとき0、負のとき-1) |
| ceiling | R→R | 指定した数以上の数のうち、最小の整数値 |
| floor | R→R | 指定した数以下の数のうち、最大の整数値 |
| round | R→R | 最も近い整数 |
| truncate | R→R | 整数部(0 に向かって最も近い整数) |
| phase | N→N | 極座標の偏角 |
| rot | R×R→N | 実数部と虚数部から絶対値1の複素数を作る |
| atan2 | R×R→N | 座標で指定された点の偏角 |
| N→N | ステータス領域に数値を出力する(結果は入力された値) |
定義しなくても使える「システム標準定数」は次のものがあります。
| 名前 | 型 | 意味 |
|---|---|---|
| u | L | 単位線分だけからなる集合 |
| i | N | 虚数単位 |
| e | R | 自然対数の底 |
| pi | R | 円周率 |
「フラクタル7」では繰り返しの回数を指定することができます。
「繰り返し式」の値の型は L または N→L です。 型が L のとき値を t とすると、指定した繰り返しの回数 n に対して、 線分の集合 t ^ n が結果となります。 型が N→L のとき値を関数 f とすると、指定した繰り返しの回数 n に対して、 線分の集合 f(n) が結果となります。
| 演算子 | 意味 |
|---|---|
| -、!、~ | 単項演算子 |
| *、/ | 乗法、除法 |
| +、– | 加法、減法 |
| <、>、<=、>= | 関係演算子 |
| ==、!= | 等価比較 |
| & | 変換の合成 |
| ^ | 累乗、変換の繰り返し |
| | | 変換の和集合 |
| && | 論理積 |
| || | 論理和 |
| c ? t : f | 条件演算子 |
| .. | 範囲(C#の優先順位とは異なります) |
| =、=> | 変数、関数の定義 |