yasuokaの日記: Z80における2π/48の回転行列 2
昨日の日記を読み返しながら、そう言えば当時の私(安岡孝一)は、2π/48の回転行列をZ80で作りたかったが断念した、ということを思い出した。とっくの昔にあきらめた夢のはずだが、今の私ならどうするだろう。
sin(2π/48)を2進数表記すると0.00100001011010100010…、tan(π/48)を2進数表記すると0.00010000110001110111…、どちらもスジの良くないビットパターンなのだが、とりあえずsin(2π/48)≒67/512, tan(π/48)≒67/1024あたりで、Paethの回転アルゴリズムを使ってみよう。
┌ 1 -67/1024 ┐┌ 1 0 ┐┌ 1 -67/1024 ┐
└ 0 1 ┘└ 67/512 1 ┘└ 0 1 ┘
対象とするCPUがZ80なので、IXレジスタにx座標(上位8ビットが符号付整数、下位8ビットが256を分母とする分数)を、IYレジスタにy座標を入れることにする。
FD E5 PUSH IY
E1 POP HL
CB 2C SRA H
CB 1D RR L
7C LD A,H
CB 2C SRA H
CB 1D RR L
84 ADD A,H
4F LD C,A
9F SBC A,A
47 LD B,A
CB 2C SRA H
CB 1D RR L
CB 2C SRA H
CB 1D RR L
09 ADD HL,BC
EB EX DE,HL
DD E5 PUSH IX
E1 POP HL
B7 OR A
ED 52 SBC HL,DE
54 LD D,H
5D LD E,L
7C LD A,H
CB 2C SRA H
CB 1D RR L
84 ADD A,H
4F LD C,A
9F SBC A,A
47 LD B,A
CB 2C SRA H
CB 1D RR L
CB 2C SRA H
CB 1D RR L
09 ADD HL,BC
44 LD B,H
4D LD C,L
FD 09 ADD IY,BC
FD E5 PUSH IY
E1 POP HL
CB 2C SRA H
CB 1D RR L
7C LD A,H
CB 2C SRA H
CB 1D RR L
84 ADD A,H
4F LD C,A
9F SBC A,A
47 LD B,A
CB 2C SRA H
CB 1D RR L
CB 2C SRA H
CB 1D RR L
09 ADD HL,BC
EB EX DE,HL
B7 OR A
ED 52 SBC HL,DE
E5 PUSH HL
DD E1 POP IX
C9 RET
(100,0)すなわちIX=6400H, IY=0000Hから始めると、このプログラムは48回よびだしたところでIX=6402H, IY=004EHとなった。x座標はほぼ元の位置に戻っているが、y座標の方は0.3ドットほど回りすぎだ。まあ、これでも十分な気がするが、これ、回転精度をもう少しだけ上げるには、どういう風にいじればいいのかな…。
結局テーブルを使ったほうが速い&早い? (スコア:1)
コードが長くなってくると
1/4π分のテーブルを用意するという(有る意味)残念な方法との比較も必要になりますね
ASCII 1983年7月号 (スコア:2)
はい。当時の私(安岡孝一)は「FEDORA」(ASCII, Vol.7, No.7 (1983年7月), pp.143-149)っていうゲームを作ってたんですけど、回転行列をうまく書くことができず、定数ベクトルの逆数テーブルにしてしまいました。