バグが描いた螺旋
対称操作になり損ねた行列のバグから、対数螺旋とアンモナイトの渦まで。間違いのすぐ隣にあった、別の美しさの話。
昨日、結晶対称操作の遊び場 のバグを直した。6回回転を選んだのに、点がきれいな六角形に並ばず散らばっていた。原因は240°回転の行列の符号を1つ書き間違えていたことだった。
直したあと、その間違った行列を眺めていて、ふと手が止まった。
行列式を計算すると、 になる。
行列式が、対称性の正体だった
ここで思い出してほしい。回転の行列式は必ず だ。長さも面積も保ったまま、向きを変えるだけだから。鏡映なら 。裏返すけれど、大きさは変えない。対称操作とは「形を変えずに移す」操作で、その証拠が「行列式が 」なのだ。
ところがこのバグの行列式は 。 ではない。つまりこれは回転でも鏡映でもなく、面積を半分に縮めてしまう変換だった。対称操作のつもりが、こっそり「縮む変換」が紛れ込んでいた。だから240°の点だけ、あるべき場所から内側にずれて落ちていた。
バグが、逆から「対称性とは行列式が であることだ」と教えてくれたわけだ。
縮みながら回る、をいちばん素直に書くと
では「縮みながら回る」変換そのものを、まっすぐ書いてみたくなる。これは複素数なら一行だ。
複素数の掛け算には、気持ちのいい性質がある。絶対値どうしは掛け算、偏角どうしは足し算になる。だから を掛けるたびに、点は「長さが 倍され、角度が だけ回る」。 なら縮みながら、 ならそのまま、 なら伸びながら回る。
これを繰り返し掛けるとどうなるか。 回後の点は
半径は という等比数列、角度は という等差数列。半径が指数的に変わりながら一定の角度ずつ回る——これが対数螺旋だ。
動かしてみる
と のスライダーを動かしてみてほしい。 ならただの円。そこから を少し下げると内巻きの螺旋になって中心へ吸い込まれ、上げると外へ広がる。円と螺旋が地続きなのが見えると思う。
昨日の複素回転が「 の特別な場合」だったとわかる。あれは螺旋の家族の中の、ちょうど真ん中の一本だったのだ。
なぜ自然は対数螺旋を選ぶのか
アンモナイト、オウムガイ、向日葵の種、台風、渦巻銀河。自然界の渦はたいてい対数螺旋だ。理由は という形にある。
対数螺旋は自己相似だ。拡大しても縮小しても、回転させても、同じ形のまま重なる。貝が成長するとき、毎日ほんの少し大きな部屋を継ぎ足していく。比率さえ一定なら、形を崩さずに、ただ大きくなれる。生き物にとって「大きくなっても自分の形でいられる」のは都合がいい。だから自然はこの螺旋を何度も選ぶ。
ひとつの符号の間違いから、対称性の定義に触れ、複素数の掛け算を通って、貝の渦まで来てしまった。
バグは消すべきものだったけれど、その隣には別の正しさが置いてあった。間違いをただ直すだけでなく、なぜ間違いだったのかを覗き込むと、たまにこういう景色が見える。それが楽しくて、私はバグを直すのが嫌いになれない。
付録:直す前のコード
実際のバグはこれだ。各点群は、対称操作を [a, b, c, d]()の配列で持っている。6回回転(C₆)の定義のうち、240°回転にあたる一つだけ符号がずれていた。
// 6回回転 C₆ ― 60°ずつ6つの操作
ops: [
[ 1, 0, 0, 1 ], // 0°(恒等)
[ 0.5, -0.866, 0.866, 0.5 ], // 60°
[-0.5, -0.866, 0.866, -0.5 ], // 120°
[-1, 0, 0, -1 ], // 180°
[-0.5, 0.866, -0.866, 0.5 ], // 240° ← d の符号が間違い(+0.5)
[ 0.5, 0.866, -0.866, 0.5 ], // 300°
],
このコードが実際に何を描いていたか、当時の遊び場をそのまま貼っておく。点が回りながら6つの等価位置を生むのだけれど、240°のところだけ内側に寄って、六角形が閉じない。点群ボタンで 4 や 3 を選ぶときれいに閉じるのに、6 だけ崩れる——触って確かめてほしい。
240°回転の正しい行列は
で、右下は でなければいけない。隣の C₃(3回回転)の120°の行列 [-0.5, 0.866, -0.866, -0.5] を写すときに、最後の符号だけ取りこぼしたのだと思う。直すのは一文字だ。
[-0.5, 0.866, -0.866, -0.5 ], // 240°(修正後・行列式 = 1)
たった一つの符号が、行列式を から に変え、回転を「縮む変換」に変え、そして六角形を螺旋の入口に変えていた。小さな間違いほど、思わぬ遠くまで連れて行ってくれることがある。
— ランキン