1 #include <stdio.h>
2 #include <math.h>
3 #include <stdint.h>
4
5 #define PI (3.14159265358979323846264338327950288)
6
7 /* Row Col */
8 int atan2table[100][100];
9 const int tableSize = (int)
(sizeof(atan2table ) /
sizeof(atan2table[0][0]));
10 const int tableColumn = (int) (sizeof(atan2table[0]) /
sizeof(atan2table[0][0]));
11 const int tableRow =
(int)((sizeof(atan2table ) /
sizeof(atan2table[0][0])) /
12 (sizeof(atan2table[0])
/ sizeof(atan2table[0][0])));
13
14 void createTable(void) {
15 int x, y;
16
17 for (x = 0; x < tableRow;
x++) {
18 for (y = 0; y <
tableColumn; y++)
19 { atan2table[x][y] =
(int)((atan2(y + 1, x + 1) * (180.0 / PI)) * 1000); }
20 }
21 }
22
23 int ATAN2(y, x) {
24 int xp = 1;
25 int yp = 1;
26
27 if (!x && !y) { return(0); }
28
29 if (!x) { if (y > 0) {
return(90000); } else { return(-90000); } }
30 if (!y) { if (x > 0) {
return( 0); } else { return(180000); }
}
31
32 if (x < 0) { x = -x; xp = -1;
}
33 if (y < 0) { y = -y; yp = -1;
}
34
35 x--; y--;
36
37 if (x >= tableRow) { return(0); }
38 if (y >= tableColumn) {
return(0); }
39
40 int deg = atan2table[x][y];
41
42 if (xp == -1) { deg = 180000 - deg;
}
43 if (yp == -1) { deg = -deg; }
44
45 return(deg);
46 }
47
48 int main(void) {
49 int i;
50
51 createTable();
52
53 for (i = 0; i < 360; i += 5)
{
54 int x = sin(i * (PI /
180.0)) * 95;
55 int y = cos(i * (PI /
180.0)) * 95;
56 double _atan2 = atan2(y, x)
* (180.0 / PI);
57 double _ATAN2 = ATAN2(y, x)
* 0.001;
58
59 printf("deg:%3d,
", i);
60 printf("x:%3d, y:%3d,
", x, y);
61 printf("%8.3lf, ",
_atan2);
62 printf("%8.3lf, ",
_ATAN2);
63 printf("%6.3lf, ",
_atan2 - _ATAN2);
64 printf("\n");
65 }
66
67 return(0);
68 }
69
入力範囲はx,y共に-100 - +100の間です(デフォルトのテーブルサイズでは)
このコードでは予めmatn.hのatan2でテーブルを作成していますが、組み込み用途向けの場合は予めテーブルをCSVとして作成しておき、配列に読み込んでROMに焼く という方法が使えます
また、入力がテーブルを超えた場合はテーブルに収まるように除算してから処理する というアルゴリズムにすれば精度は落ちますが広い範囲の入力を受けることができます
このコードではハードコードされた値があるため、intの代わりにshortにしようと思うとちょっと面倒ですが、uint16_tでテーブルを作った場合、100x100だと20kByteくらいのROMが必要になります
精度は悪く、ifの連続なので処理速度も期待できませんが、ソフトウェアで浮動小数点を計算するとか、そもそも浮動小数点が使えない環境では使えるかも
このコードでは予めmatn.hのatan2でテーブルを作成していますが、組み込み用途向けの場合は予めテーブルをCSVとして作成しておき、配列に読み込んでROMに焼く という方法が使えます
また、入力がテーブルを超えた場合はテーブルに収まるように除算してから処理する というアルゴリズムにすれば精度は落ちますが広い範囲の入力を受けることができます
このコードではハードコードされた値があるため、intの代わりにshortにしようと思うとちょっと面倒ですが、uint16_tでテーブルを作った場合、100x100だと20kByteくらいのROMが必要になります
精度は悪く、ifの連続なので処理速度も期待できませんが、ソフトウェアで浮動小数点を計算するとか、そもそも浮動小数点が使えない環境では使えるかも
0 件のコメント:
コメントを投稿