Arduboyで狙い撃つぜ!(atan2テーブルの作り方) その6

前回とは異なる方法で、atan2を実装できそうだ。

レーダー法
http://beach.biwako.ne.jp/~beaver/msx/msxtecho/table2.htm


画面をマス目状に分割し、画面の中心からそれぞれのマス目が、
どの角度になるかをテーブル化しているようだ。

1030 DEFINT A-Z:DIM TX(8),TY(8),SN!(31),CS!(31),RT(30,22),HX(1),HY(1)
1080 'ATN テーブルの じゅんび
1090 FOR Y=1TO11:RT(15+Y,11+Y)=4:RT(15,11+Y)=8:RT(15-Y,11+Y)=12:RT(15-Y,11-Y)=20:RT(15,11-Y)=24:RT(15+Y,11-Y)=28:NEXT:FOR X=1TO15:RT(15+X,11)=0:RT(15-X,11)=16:NEXT:RT(15,11)=8
1100 FOR X=2TO11:FOR Y=1TO X-1:I=31AND(5.09295ATN(Y/X)):RT(15+X,11+Y)=I:RT(15+Y,11+X)=8-I:RT(15-Y,11+X)=8+I:RT(15-X,11+Y)=16-I:RT(15-X,11-Y)=16+I:RT(15-Y,11-X)=24-I:RT(15+Y,11-X)=24+I:RT(15+X,11-Y)=31AND(-I):NEXT:NEXT
1110 FOR X=12TO15:FOR Y=1TO11:I=31AND(5.09295ATN(Y/X)):RT(15+X,11+Y)=I:RT(15-X,11+Y)=16-I:RT(15-X,11-Y)=16+I:RT(15+X,11-Y)=31AND(-I):NEXT:NEXT


BASICで書かれているものを、Pythonで書き直した。

import math

# 1030 DEFINT A-Z:DIM TX(8),TY(8),SN!(31),CS!(31),RT(30,22),HX(1),HY(1)
RT = [[0] * (22+1) for i in range(30+1)]

#1090 FOR Y=1TO11:RT(15+Y,11+Y)=4:RT(15,11+Y)=8:RT(15-Y,11+Y)=12:RT(15-Y,11-Y)=20:RT(15,11-Y)=24:RT(15+Y,11-Y)=28:NEXT:FOR X=1TO15:RT(15+X,11)=0:RT(15-X,11)=16:NEXT:RT(15,11)=8
for Y in range(1, 11+1):
    RT[15+Y][11+Y] = 4
    RT[15][11+Y]   = 8
    RT[15-Y][11+Y] = 12
    RT[15-Y][11-Y] = 20
    RT[15][11-Y]   = 24
    RT[15+Y][11-Y] = 28
for X in range(1, 15+1):
    RT[15+X][11] = 0
    RT[15-X][11] = 16
RT[15][11] = 8

#1100 FOR X=2TO11:FOR Y=1TO X-1:I=31AND(5.09295*ATN(Y/X)):RT(15+X,11+Y)=I:RT(15+Y,11+X)=8-I:RT(15-Y,11+X)=8+I:RT(15-X,11+Y)=16-I:RT(15-X,11-Y)=16+I:RT(15-Y,11-X)=24-I:RT(15+Y,11-X)=24+I:RT(15+X,11-Y)=31AND(-I):NEXT:NEXT
for X in range(2, 11+1):
    for Y in range(1, X-1+1):
        I = int(31 and (5.09295 * math.atan(Y/X)))
        RT[15+X][11+Y] = I
        RT[15+Y][11+X] = 8-I
        RT[15-Y][11+X] = 8+I
        RT[15-X][11+Y] = 16-I
        RT[15-X][11-Y] = 16+I
        RT[15-Y][11-X] = 24-I
        RT[15+Y][11-X] = 24+I
        RT[15+X][11-Y] = 31 and (-I)

#1110 FOR X=12TO15:FOR Y=1TO11:I=31AND(5.09295*ATN(Y/X)):RT(15+X,11+Y)=I:RT(15-X,11+Y)=16-I:RT(15-X,11-Y)=16+I:RT(15+X,11-Y)=31AND(-I):NEXT:NEXT
for X in range(12, 15+1):
    for Y in range(1, 11+1):
        I = int(31 and (5.09295 * math.atan(Y/X)))
        RT[15+X][11+Y] = I
        RT[15-X][11+Y] = 16-I
        RT[15-X][11-Y] = 16+I
        RT[15+X][11-Y] = 31 and (-I)

for y in range(22+1):
    for x in range(30+1):
        print(format(RT[x][y], '#2') + ',', end='')
    print('')

csvで出力。

19,19,19,19,20,21,21,21,22,22,22,23,23,24,24,24,24,24,25,25,26,26,26,27,27,27,28,-3,-3,-3,-3,
18,19,19,19,19,20,21,21,21,22,22,23,23,23,24,24,24,25,25,25,26,26,27,27,27,28,-3,-3,-3,-3,-2,
18,18,19,19,19,19,20,21,21,22,22,22,23,23,24,24,24,25,25,26,26,26,27,27,28,-3,-3,-3,-3,-2,-2,
18,18,18,18,19,19,19,20,21,21,22,22,23,23,24,24,24,25,25,26,26,27,27,28,-3,-3,-3,-2,-2,-2,-2,
18,18,18,18,18,19,19,19,20,21,21,22,22,23,24,24,24,25,26,26,27,27,28,-3,-3,-3,-2,-2,-2,-2,-2,
17,18,18,18,18,18,18,19,19,20,21,22,22,23,24,24,24,25,26,26,27,28,-3,-3,-2,-2,-2,-2,-2,-2,-1,
17,17,17,18,18,18,18,18,19,19,20,21,22,23,23,24,25,25,26,27,28,-3,-3,-2,-2,-2,-2,-2,-1,-1,-1,
17,17,17,17,17,17,18,18,18,18,19,20,21,22,23,24,25,26,27,28,-3,-2,-2,-2,-2,-1,-1,-1,-1,-1,-1,
17,17,17,17,17,17,17,17,18,18,18,19,20,22,23,24,25,26,28,-3,-2,-2,-2,-1,-1,-1,-1,-1,-1,-1,-1,
16,16,16,16,16,17,17,17,17,17,17,18,18,20,22,24,26,28,-2,-2,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0,
16,16,16,16,16,16,16,16,16,16,17,17,17,18,20,24,28,-2,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,16,16,16,16,16,16,16,16,16,15,15,15,14,12, 8, 4, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
16,16,16,16,16,15,15,15,15,15,15,14,14,12,10, 8, 6, 4, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
15,15,15,15,15,15,15,15,14,14,14,13,12,10, 9, 8, 7, 6, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
15,15,15,15,15,15,14,14,14,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
15,15,15,14,14,14,14,14,13,13,12,11,10, 9, 9, 8, 7, 7, 6, 5, 4, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1,
15,14,14,14,14,14,14,13,13,12,11,10,10, 9, 8, 8, 8, 7, 6, 6, 5, 4, 3, 3, 2, 2, 2, 2, 2, 2, 1,
14,14,14,14,14,13,13,13,12,11,11,10,10, 9, 8, 8, 8, 7, 6, 6, 5, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2,
14,14,14,14,13,13,13,12,11,11,10,10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 5, 5, 4, 3, 3, 3, 2, 2, 2, 2,
14,14,13,13,13,13,12,11,11,10,10,10, 9, 9, 8, 8, 8, 7, 7, 6, 6, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2,
14,13,13,13,13,12,11,11,11,10,10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 5, 5, 5, 4, 3, 3, 3, 3, 2,
13,13,13,13,12,11,11,11,10,10,10, 9, 9, 8, 8, 8, 8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 4, 3, 3, 3, 3,

Numbersで読み込み、角度ごとに手作業で色分けしてみた。

f:id:raohu69:20180701150129p:plain

画面を31x23に分割し、1周を32分割した角度テーブルになっている。

1マスを16x16ドットで考えると、画面サイズが496x368ドット。
1マスを8x8ドットで考えると、画面サイズが248x184ドット。
この範囲を越えると正しく方向が求められなくなるので、気をつける必要がある。

I = int(31 and (5.09295 * math.atan(Y/X)))

この「5.09295」という値の意味が分からないが、
どのようなテーブルを作れば良いのかは分かった。