■ 回転について
テトリスブロックを↓のように、配列の配列で表現している。
block = [
[0,0,1],
[1,1,1]
]
つまり、点(x,y)の状態を調べたければ、block[y][x]を調べればよいわけなのである。
しかし、これを回転させるにはどうすればよいかがはじめよくわからなくて困った。
試行錯誤している内に以下が一般解であることがわかった。以下は左に90度回転した場合。
for(var y=0;y<yLength;y++){
for(var x=0;x<xLength;x++){
/*
* x,y座標のそれぞれに対し、新しいブロック中の点(x, y)に
* (yLength-1-y, x)を代入。
*/
newBlock[y][x] = oldBlock[x][yLength-1-y];
}
}
「yLength-1-y」は、後ろから数えた順番。
(yLength-1が最大値だから、最大値-y で後ろから数えた順番にしているのだ)。
つまりx座標とy座標を入れ替えて、さらにy座標の方を逆転させると左90度回転になるらしい。同様に、x座標y座標を入れ替えたあと、x座標の方を逆転させると右90度回転になるらしい。
ここまでは試行錯誤しているうちに何とかわかったんだけど、なんでそうなるのかがわからなかった。どうやらこれが噂に聞く行列とか三角関数の問題なのだろうと思った。
今日M川に会ったら、M川が線形代数の勉強をしていたので、いろいろ聞きながら考えた。
まず結論から言うと、これは行列の問題で、以下のような公式が使える。
原点を中心に点(x,y)をθ回転させた座標は、
(x*cosθ - y*sinθ, x*sinθ+y*cosθ)
となる。
θ = 90度の場合、
cosθ=0, sinθ=1より、
(-y,x)となる。
やっぱり、xとyを入れ替えてyを逆転させるのでよいらしい。
行列の計算はよくわからないのだが、自分としては以下のように考えると、この公式が出てくる理由がわかりやすいように思った。
まず点(x,y)を(x,0)と(0,y)の2つに分解する。
点(x,0)をθ回転させると、(x*cosθ, x*sinθ)になる。これはcos, sinの定義より自明。
同様に
点(0,y)をθ回転させると、(-y*sinθ, y*cosθ)になる。

あとは(x*cosθ, x*sinθ), (-y*sinθ, y*cosθ)の2つの点を再び合成すれば、(x,y)をθ度回転した点が得られ、公式通りとなる。
(x*cosθ - y*sinθ, x*sinθ+y*cosθ).
コメント(2)
コメントする
トラックバック(0)
このブログ記事を参照しているブログ一覧: 雑記2008年2月23日(土)
このブログ記事に対するトラックバックURL: http://www.at-akada.org/mt/mt-tb.cgi/886
this is the coolest place ever! After visiting all kinds of sites, I figured out that this one is the most interesting
』 (2008/04/ 7 3:55)That IS progress. Your blogging skills are getting better and better. I had a great time reading this post.
』 (2008/04/ 9 19:15)