エレファント・ビジュアライザー調査記録

ビジュアルプログラミングで数式の変形を表すことを考えていくブロクです。

フラクタル(4)

Blockly デベロッパー ツール  |  Google Developers」を使ってフラクタルを記述する「フラクタル(Blockly)」では、JavaScriptで記述できるものと同様のものをBlocklyで書いて「変換リスト」を作成するようになっています。(バージョン1)

これを改造して、バージョン2では「変換リスト」を直接書くためのBlocklyの要素を追加します。

平面上の点を複素平面上の複素数と考えます。

複素数  a b c に対して  c' = a + (b-a)c とおくと
 \cfrac{c'-a}{c-0} = \cfrac{(b-a)c}{c} = b-a
 \cfrac{c'-b}{c-1} = \cfrac{(a-b)+(b-a)c}{c-1} = b-a
が成り立ちます。よって
 \cfrac{b-a}{1-0} = \cfrac{c'-a}{c-0} = \cfrac{c'-b}{c-1}
となり複素平面上で  0 1 c を頂点とする三角形と  a b c' を頂点とする三角形は相似となります。

 a b を両端とする線分を  [a,b] と書くことにします。線分  [c,d] による線分  [a,b] の変換を  t_{[c,d]}([a,b]) = [a + (b-a)c,a + (b-a)d]
とおきます。変換の集合  T による線分の集合  L の変換  T(L)
 T(L) = \{t(l) \mid t \in T, l \in L\}
とおきます。この変換を  k 回繰り返したものを  T^k(L) とします。

バージョン1

バージョン1では変換リストは点のリスト(分点リスト)または線のリスト(線分リスト)となります。「線分リスト」チェックボックスをチェックすると線分リストとなります。

変換リスト(分点リスト)

点をx座標  x とy座標  y からなるリスト  [x,y] で表します。点のリスト  [ p_1, p_2, \cdots, p_n ] は、変換の集合  T = \{t_{[0,p_1]}, t_{[p_1,p_2]}, \cdots, t_{[p_{n-1},p_n]}, t_{[p_n,1]}\} を表すものとします。「繰り返しの回数」が  k のとき(通常は)  T^k(L) を表示します。「すべての線を表示」のときは  L \cup T(L) \cup \cdots \cup T^k(L) を表示します。

変換リスト(線分リスト)

線分を始点  p と終点  q からなるリスト  [p,q] で表します。線分のリスト  [ l_1, l_2, \cdots, l_n ] は、変換の集合  T = \{t_{l_1}, t_{l_2}, \cdots, t_{l_n}\} を表すものとします。「繰り返しの回数」が  k のとき(通常は)  T^k(L) を表示します。「すべての線を表示」のときは  L \cup T(L) \cup \cdots \cup T^k(L) を表示します。

バージョン2

バージョン2では、変換リストは
 [ v, x_1, x_2, \cdots, x_e]
というリストです。 v はバージョン情報です(バージョン2では2)。 x_1, x_2, \cdots, x_e の各  x_i はバージョン1の変換リスト(点のリストまたは線分のリスト)を拡張したものです。バージョン2ではこれを複数指定することができます。

点のリストを拡張したものは
 [ p'_1, p'_2, \cdots, p'_n]
というリストで、各  p'_i
 [ p_i ] または  [ p_i, d_i ] または  [ p_i, d_i, f_i ] または  [ p_i, d_i, f_i, c_i, r_i, g_i, b_i ]
というリスト(拡張された点の情報)です。各  p_i は点を表します(バージョン1の点と同じもの)。

線分のリストを拡張したものは
 [ l'_1, l'_2, \cdots, l'_n]
というリストで、各  l'_i
 [ l_i ] または  [ l_i, d_i ] または  [ l_i, d_i, f_i ] または  [ l_i, d_i, f_i, c_i, r_i, g_i, b_i ]
というリスト(拡張された線分の情報)です。各  l_i は線分を表します(バージョン1の線分と同じもの)。

 d_i, f_i, c_i, r_i, g_i, b_i は以下の情報を表します。

 d_i 表示と継承情報
 f_i 次の変換の番号
 c_i 色の変更情報
 r_i 色を変更するときの色情報(R)
 g_i 色を変更するときの色情報(G)
 b_i 色を変更するときの色情報(B)
表示と継承情報

表示と継承情報は以下のようになります。

0 最後だけ表示 この線分は表示されないが、次の変換の元として使われ、最後に変換されたものだけが表示される
1 すべて表示 この線分は表示され、かつ次の変換の元としても使われる
2 表示しない この線分は表示されず、次の変換でも使われない
3 表示する この線分は表示されるが、次の変換では使われない

省略すると「最後だけ表示」となります。

次の変換の番号

次の変換の番号は上記の  x_1, x_2, \cdots, x_e の各  x_i i を表しますが、インデックスは  0 から始まります(つまり  i-1 となります)。省略すると  0 となります。

色の変更情報

色の変更情報は以下のようになります。

0 変更しない 変数  R, G, B で指定した色(既定値)で表示する
1 変更する  r_i, g_i, b_i で指定した色で表示する
2 増加 その時点の色のRGB成分を  r_i, g_i, b_i の分増加させて表示する
3 減少 その時点の色のRGB成分を  r_i, g_i, b_i の分減少させて表示する

省略すると「変更しない」となります。

変換の拡張

線分の情報を拡張して
 [ l, d, f, r, g, b ]
というリスト(線分表示情報)を考えます。線分表示情報の内容は以下のようになります。

 l 線分
 d 表示と継承情報
 f 次の変換の番号
 r 色情報(R)
 g 色情報(G)
 b 色情報(B)

この線分表示情報を  \sigma とおきます。

線分表示情報  \sigma = [ l, d, f, r, g, b ] の拡張された線分の情報  \lambda = [ l', d', f', c', r', g', b' ] による変換  t'_{\lambda}(\sigma) を考えます。

 t'_{\lambda}(\sigma) = [ t_{l'}(l), d'', f', r'', g'', b'' ] とします。 d'' は以下のようになります。

 d  d''
最後だけ表示またはすべて表示  d'
表示しないまたは表示する 表示しない

 r'' g'' b'' c' に従って以下のようになります。

 c'  r''  g''  b''
変更しない  r  g  b
変更する  r'  g'  b'
増加  r + r'  g + g'  b + b'
減少  r - r'  g - g'  b - b'

線分表示情報の集合  L に対して
 D(L) = \{ [ l, d, f, r, g, b ] \mid d \ は「すべて表示」または「表示する」 \}
 E(L) = \{ [ l, d, f, r, g, b ] \mid d \ は「最後だけ表示」 \}
 H_j(L) = \{ [ l, d, f, r, g, b ] \mid d \ は「最後だけ表示」または「すべて表示」、f = j-1 \}
とおきます。

変換リスト  X = [ v, x_1, x_2, \cdots, x_e] の各  x_i に対応する拡張された線分による変換の集合を  T'_{i} とするとき  X による変換  G_X
 G_X(L) = T'_1(H_1(L)) \cup T'_2(H_2(L)) \cup \cdots \cup T'_{e}(H_e(L))
と定義します。

この変換を  k 回繰り返したものを  G_X^k(L) とします。

変換リスト  X = [ v, x_1, x_2, \cdots, x_e] の各  x_i を部分リストと呼ぶことにします。部分リストが拡張された線分のリストのとき
 E(G_X^k(L)) \cup D(L) \cup D(G_X(L)) \cup D(G_X^2(L)) \cup \cdots \cup D(G_X^k(L))
を表示します。

部分リストが拡張された点のリストの場合は以下のようになります。

部分リストが拡張された点のリストの場合

拡張された点のリスト
 [ p'_1, p'_2, \cdots, p'_n]
で、各  p'_i [ p_i, d_i, f_i, c_i, r_i, g_i, b_i ] であるものを考えます(省略可能なものは省略できるとします)。

これに対応する拡張された線分のリストを
 [ l'_1, l'_2, \cdots, l'_n, l'_{n+1}]
とし、各  l'_i [ l_i, d_i, f_i, c_i, r_i, g_i, b_i ] であるとします。
 l_1 = [0, p_1]
 l_i = [p_{i-1}, p_i] ( i = 2,3,\cdots,n)
 l_{n+1} = [p_n, 1]
 d_{n+1} は「最後だけ表示」
 f_{n+1} = 0
 c_{n+1} は「変更しない」
とします。この拡張された線分のリストに対して
 E(G_X^k(L)) \cup D(L) \cup D(G_X(L)) \cup D(G_X^2(L)) \cup \cdots \cup D(G_X^k(L))
を表示します。

「すべての線を表示」がチェックされたとき

バージョン2では必要はないのですが、「すべての線を表示」がチェックされたときは
 L \cup G_X(L) \cup G_X^2(L) \cup \cdots \cup G_X^k(L)
を表示することにします。