iatan2.c

00001 /*
00002   \brief 整数型の atan2()
00003 
00004   Integer Arc Tangent program ( iatan2()
00005   !!! Attention.  This program generated by create_iatan2.rb. !!!
00006 
00007   \author Satofumi KAMIMURA
00008 
00009   $Id: generateaTan2.rb,v 1.1 2004/06/09 01:07:20 satofumi Exp $
00010 
00011   angle_max = 65535
00012 
00013   現在の実装では、33/65535 以内の誤差が生じる。
00014   一応、2^(31-13) までの距離が X, Y において使えるはず
00015 */
00016 
00017 #include "iatan2.h"
00018 
00019 static short atan2_table[] = {
00020 0, 25, 50, 75, 101, 126, 151, 176, 201, 226, 
00021 251, 277, 302, 327, 352, 377, 402, 428, 453, 478, 
00022 503, 529, 554, 579, 604, 630, 655, 680, 705, 731, 
00023 756, 781, 807, 832, 858, 883, 908, 934, 959, 985, 
00024 1010, 1036, 1061, 1087, 1113, 1138, 1164, 1189, 1215, 1241, 
00025 1267, 1292, 1318, 1344, 1370, 1396, 1421, 1447, 1473, 1499, 
00026 1525, 1551, 1577, 1603, 1629, 1656, 1682, 1708, 1734, 1761, 
00027 1787, 1813, 1840, 1866, 1892, 1919, 1945, 1972, 1999, 2025, 
00028 2052, 2079, 2105, 2132, 2159, 2186, 2213, 2240, 2267, 2294, 
00029 2321, 2348, 2376, 2403, 2430, 2458, 2485, 2512, 2540, 2568, 
00030 2595, 2623, 2651, 2678, 2706, 2734, 2762, 2790, 2818, 2846, 
00031 2875, 2903, 2931, 2960, 2988, 3016, 3045, 3074, 3102, 3131, 
00032 3160, 3189, 3218, 3247, 3276, 3305, 3334, 3364, 3393, 3423, 
00033 3452, 3482, 3512, 3541, 3571, 3601, 3631, 3661, 3692, 3722, 
00034 3752, 3783, 3813, 3844, 3875, 3905, 3936, 3967, 3998, 4029, 
00035 4061, 4092, 4124, 4155, 4187, 4218, 4250, 4282, 4314, 4346, 
00036 4379, 4411, 4444, 4476, 4509, 4542, 4575, 4608, 4641, 4674, 
00037 4707, 4741, 4774, 4808, 4842, 4876, 4910, 4944, 4979, 5013, 
00038 5048, 5083, 5117, 5152, 5188, 5223, 5258, 5294, 5329, 5365, 
00039 5401, 5437, 5474, 5510, 5547, 5583, 5620, 5657, 5695, 5732, 
00040 5769, 5807, 5845, 5883, 5921, 5960, 5998, 6037, 6076, 6115, 
00041 6154, 6193, 6233, 6273, 6313, 6353, 6393, 6434, 6474, 6515, 
00042 6556, 6598, 6639, 6681, 6723, 6765, 6808, 6850, 6893, 6936, 
00043 6979, 7023, 7066, 7110, 7155, 7199, 7244, 7289, 7334, 7379, 
00044 7425, 7471, 7517, 7563, 7610, 7657, 7704, 7752, 7799, 7847, 
00045 7896, 7944, 7993, 8043, 8092, 8142, 8192, 8193
00046 };
00047 
00048 static int atanValue(int y, int x, int sign_offset) {
00049     short *p = atan2_table;
00050     short v;
00051     int ret;
00052     int offset;
00053 
00054     short *first, *last, *pre;
00055 
00056     offset = (sign_offset < 0) ? -sign_offset : sign_offset ;
00057 
00058     if (x == 0) {
00059         ;                       /* 探索は必要ない、先頭の値をそのまま返す */
00060     } else {
00061         v = y * 8192 / x;
00062         v = (v < 0) ? -v : v;
00063         first = atan2_table;
00064         last = atan2_table + 256;
00065 
00066         do {
00067             pre = p;
00068             p = atan2_table + ((first-atan2_table) + (last-atan2_table)) / 2;
00069             if (*p > v) {
00070                 last = p;
00071             } else {
00072                 first = p;
00073             }
00074         } while (p != pre);
00075     }
00076     ret = (int)((p - atan2_table) * 32);
00077 
00078     if (sign_offset < 0) {
00079         ret = offset - ret;
00080     } else {
00081         ret += offset;
00082     }
00083 
00084     return ret;
00085 }
00086 
00087 #define DEG(X) (int)(1.0 * 65536 * X / 360.0)
00088 
00099 int iatan2(int y, int x) {
00100     int ret;
00101 
00102     if (y >= 0) {
00103         if (x >= 0) {           /* 第1象限 */
00104             if (x >= y) {       /* 0-45[deg] */
00105                 ret = atanValue(y, x, DEG(0));
00106             } else {            /* 45-90[deg] */
00107                 ret = atanValue(x, y, DEG(-90));
00108             }
00109         } else {                /* 第2象限 */
00110             if (-x <= y) {      /* 90-135[deg] */
00111                 ret = atanValue(x, y, DEG(90));
00112             } else {            /* 135-180[deg] */
00113                 ret = atanValue(y, x, DEG(-180));
00114             }
00115         }
00116     } else {
00117         if (x < 0) {            /* 第3象限 */
00118             if (-x >= -y) {     /* 180-225[deg] */
00119                 ret = atanValue(y, x, DEG(180));
00120             } else {            /* 225-270[deg] */
00121                 ret = atanValue(x, y, DEG(-270));
00122             }
00123         } else {                /* 第4象限 */
00124             if (x <= -y) {      /* 270-315[deg] */
00125                 ret = atanValue(x, y, DEG(270));
00126             } else {            /* 315-360[deg] */
00127                 ret = atanValue(y, x, -DEG(360));
00128             }
00129         }
00130     }
00131     return ret;
00132 }
00133 

Generated on Mon Apr 13 22:52:04 2009 by  doxygen 1.5.7.1