ページ 1 / 1
atan2のテーブル化について(NESASM用)
Posted: 2011年10月09日(日) 19:21
by KEYONN_
敵の弾発射処理をコーディングしようと思っているのですが、
何かと便利なatan2関数をテーブル化したいと思っています。
ファミコンの画面解像度は、256x224です。
こんな感じでatan2テーブルを利用したいのですが、
どうすれば出来ますでしょうか?
コード:
lda Enemy_X,x
sta X1
lda Enemy_Y,x
sta Y1
lda Jiki01_X
sta X2
lda Jiki01_Y
sta Y2
jsr atan2calc
sta Angle
;…最後の方
atan2: .incbin "atan2.bin"
〔注意〕256周期で変数というかレジスタがcharなので、0~255に見合った
サイズでお願いします。
[編注意]過去ログをみましたが、toyoさんの作ったatan2のテーブル化
ルーチンが見つかりませんでした。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月09日(日) 20:07
by KEYONN_
コード:
#include<stdio.h>
#include<math.h>
#define RD 3.141592653/256
int main()
{
char ATN[32][30];
int x,y;
FILE *fp;
for(x=0;x<32;x++)
{
for(y=0;y<30;y++)
{
ATN[x][y]=((int)(atan2(y,x)/RD));
}
}
fp=fopen("atan.bin","wb");
fwrite(ATN,sizeof(char),sizeof(ATN),fp);
fclose(fp);
return 0;
}
このソースをVC++6でコンパイルし、
実行してみたところ、値がバイナリエディタで
見たら、
全て0x00でした。
何故でしょうか?
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月09日(日) 21:22
by box
KEYONN_ さんが書きました:コード:
char ATN[32][30];
ATN[x][y]=((int)(atan2(y,x)/RD));
この2行の意味合いがよくわからないです。
ATN[][]はchar型でいいんですか?
また、そこに代入するとき、(おそらくdouble型の)逆正接値をintにキャストした結果を最終的にchar型に代入する、
というやり方は本当に正しいのでしょうか?
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月09日(日) 21:59
by h2so5
マクロを展開すると16行目は下のような式になりますが、意図した通りですか?
ATN[x][y]=((int)(atan2(y,x)/3.141592653/256));
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月10日(月) 12:35
by KEYONN_
h2so5 さんが書きました:マクロを展開すると16行目は下のような式になりますが、意図した通りですか?
ATN[x][y]=((int)(atan2(y,x)/3.141592653/256));
今、書籍で確認したところ、ラジアンから角度に直すには
度数=ラジアン÷180*PI;
みたいです。
どうやら間違ってたみたいです。
ただ、この場合、256周期で持ちたいので、その辺はどうなるのかは
よく分かりません。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月10日(月) 12:38
by KEYONN_
box さんが書きました:KEYONN_ さんが書きました:コード:
char ATN[32][30];
ATN[x][y]=((int)(atan2(y,x)/RD));
この2行の意味合いがよくわからないです。
ATN[][]はchar型でいいんですか?
また、そこに代入するとき、(おそらくdouble型の)逆正接値をintにキャストした結果を最終的にchar型に代入する、
というやり方は本当に正しいのでしょうか?
いえ、正しくはないと思います。intとcharではバイトのサイズが違いますので
正しくないです。何故こういう書き方をしたかというと、元のソース
で
このページがこういう書き方をしていたからです。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月12日(水) 02:55
by ISLe
ATN配列の添字は何を意味しているのでしょうか?
atanの0.0~1.0の範囲をテーブルにするのではないでしょうか。
インデックス計算するのに割り算が必要ですけど。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月14日(金) 17:12
by KEYONN_
ISLeさんへ
>ATN配列の添字は何を意味しているのでしょうか?
256x224を8で割ったものです。ただ、その場合は、32x28になるのでしょう。
実画面は、32x30なので、勘違いしていました。
>atanの0.0~1.0の範囲をテーブルにするのではないでしょうか。
>インデックス計算するのに割り算が必要ですけど。
atan関数で0.0~1.0の範囲をテーブルにするのですね。
ちょっとやってみます。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月15日(土) 17:01
by KEYONN_
擬似コードで書くとこんな感じでしょうか?
コード:
char ATN[32][28];
double i;
for(i=0.0f;i<1.0f;i+=?;)
{
ATN[?][?]=atan(i);
}
?の部分が分かりません。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月15日(土) 18:02
by ISLe
画面をタイル分割すると対象との距離が近いほど精度が低くなりますけど、そんなので良いのでしょうか?
atanの0.0~1.0のテーブルはもっと精度の高いところを目指しますので考え方が異なります。
atanの0.0~1.0は45度分にあたります。
x,yそれぞれの差分の比率からインデックスを求めるので、45度を何分割するか好きに決めて良いです。
円周を256分割する前提ということなので細かくしすぎても無駄になってしまいますけど。
申し訳ないですけど、具体的に8ビット環境の実装を考えるのはめんどうなので、以前わたしが書いたコードを紹介します。
精度が異なりますが、変形すればそのまま使える部分も多いかと思います。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月15日(土) 22:57
by KEYONN_
ISleさんへ
ありがとうございます。
参考になりそうです。
16ビット(2バイト)使って、計算したいと思います。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月15日(土) 23:21
by softya(ソフト屋)
16ビット(2バイト)でやる前にNESでもメモリが足りるガ計算したほうが良いと思います。
NESのメモリから逆算して最低限の精度が出る方法を探るのが先ですよ。
Re: atan2のテーブル化について(NESASM用)
Posted: 2011年10月16日(日) 01:14
by ISLe
先の回答で、円周65536分割を想定したコード、と書きましたけど誤りでした。
65536じゃなくて32768でした。
さらに円周一周を0~32767で表す前提になっているだけで、分割数はもっと少ないです。
異なる分割数で作った関数が二つずつ入ってますので、変更箇所の見当を付けやすいかと思います。