簡易回転計算
その昔、高校の先輩が8ビットマシンで背景が回転するゲームを作るにあたり、sinθ=1/8、cosθ=127/128として、Z80の機械語でいとも簡単に回転行列の計算をしてしまっていたのを見て、この人には追い着けないなあ、と感じたものです。どうやったらこんなの思い付けるんだろう。
— KenKenMkIISR (@KenKenMkIISR) 2016年9月10日
というツイートを見て、少し考えてみました。
角度が θ(以下、全てラジアン(弧度法)とする)で、ごく小さい( θ ≒ 0 )時、sin(θ) ≒ θ, cos(θ) ≒ 1 という近似もありますが、それとは少し違う感じです。
ピタゴラスの定理から sin2(θ) + cos2(θ) = 1 という関係がありますが、それを変形すると、互いに sin(θ) = √( 1 ー cos2(θ) ), cos(θ) = √( 1 ー sin2(θ) ) となりますので、それをちょっと考えてみます。すると次のように、cos の側から計算するとうまいこと変形できて、
√( 1 - (127/128)2 ) = √( 1 - 16129/16384 ) = √( 255/16384 ) ≒ ( 16/128 ) = 1/8
のように、cosの側を基準にするとsinがわずかに大きくなっている近似と言えます。
ここでもう少し √( 1 - ((N-1)/N)2 ) について考えてみますと、
√( 1 - ((N-1)/N)2 ) = √( 1 - (N-1)2/N2 )
= √( 1 - (N2-2N+1)/N2 )
= √( (N2-N2+2N-1)/N2 )
= √( (2N-1)/N2 )
= √(2N-1) / N
となりますので、2N(か、2N-1)がちょうど平方数になり、かつその平方根がNの約数、というような時にうまく上記の場合のような関係になることがわかります(例示の場合では N = 128、平方数が256=162)。
小さい方を考えてみますと、
N = 98 の時 97/98 と 1/7 (平方数が196=142)
N = 72 の時 71/72 と 1/6 (平方数が144=122)
といったようにして同じような関係は(誤差がだんだん大きくなりながらも)成立していますが、うまく2の冪の計算が8ビット機で使えるのは、1/8が出てくる上記の場合だけでしょう。