Rev 493 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
256 | killagreg | 1 | #include "91x_lib.h" |
2 | #include "mymath.h" |
||
493 | killagreg | 3 | #include <math.h> |
256 | killagreg | 4 | |
5 | // discrete mathematics |
||
6 | |||
7 | // sinus with argument in degree at an angular resolution of 1 degree and a discretisation of 13 bit. |
||
8 | const s16 sinlookup[91] = {0, 143, 286, 429, 571, 714, 856, 998, 1140, 1282, 1423, 1563, 1703, 1843, 1982, 2120, 2258, 2395, 2531, 2667, 2802, 2936, 3069, 3201, 3332, 3462, 3591, 3719, 3846, 3972, 4096, 4219, 4341, 4462, 4581, 4699, 4815, 4930, 5043, 5155, 5266, 5374, 5482, 5587, 5691, 5793, 5893, 5991, 6088, 6183, 6275, 6366, 6455, 6542, 6627, 6710, 6791, 6870, 6947, 7022, 7094, 7165, 7233, 7299, 7363, 7424, 7484, 7541, 7595, 7648, 7698, 7746, 7791, 7834, 7875, 7913, 7949, 7982, 8013, 8041, 8068, 8091, 8112, 8131, 8147, 8161, 8172, 8181, 8187, 8191, 8192}; |
||
330 | holgerb | 9 | //0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 38 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
10 | const s16 arccos64[65] = {90,89,88,87,86, 85, 84, 83, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 51, 50, 49, 48, 47, 45, 44, 43, 41, 40, 39, 37, 36, 34, 32, 31, 29, 27, 25, 23, 20, 18, 14, 10, 0}; |
||
256 | killagreg | 11 | |
12 | s16 c_sin_8192(s16 angle) |
||
13 | { |
||
492 | killagreg | 14 | s8 m, n; |
256 | killagreg | 15 | s16 sinus; |
16 | |||
17 | // avoid negative angles |
||
18 | if (angle < 0) |
||
19 | { |
||
20 | m = -1; |
||
21 | angle = -angle; |
||
22 | } |
||
23 | else m = +1; |
||
24 | |||
25 | // fold angle to interval 0 to 359 |
||
26 | angle %= 360; |
||
27 | |||
28 | // check quadrant |
||
29 | if (angle <= 90) n = 1; // first quadrant |
||
30 | else if ((angle > 90) && (angle <= 180)) {angle = 180 - angle; n = 1;} // second quadrant |
||
31 | else if ((angle > 180) && (angle <= 270)) {angle = angle - 180; n = -1;} // third quadrant |
||
32 | else {angle = 360 - angle; n = -1;} //fourth quadrant |
||
33 | // get lookup value |
||
34 | sinus = sinlookup[angle]; |
||
35 | // calculate sinus value |
||
36 | return (sinus * m * n); |
||
37 | } |
||
38 | |||
493 | killagreg | 39 | s16 c_arccos2(s32 a, s32 b) |
330 | holgerb | 40 | { |
491 | killagreg | 41 | if(a>b) return(0); |
42 | return(arccos64[64 * a / b]); |
||
330 | holgerb | 43 | } |
44 | |||
256 | killagreg | 45 | // cosinus with argument in degree at an angular resolution of 1 degree and a discretisation of 13 bit. |
46 | s16 c_cos_8192(s16 angle) |
||
47 | { |
||
48 | return (c_sin_8192(90 - angle)); |
||
49 | } |
||
50 | |||
293 | killagreg | 51 | // higher resolution angle in deg is arg/div |
52 | s16 c_sin_8192_res(s16 arg, s16 div) |
||
53 | { |
||
54 | s16 angle, rest; |
||
55 | s32 tmp; |
||
56 | |||
57 | angle = arg/div; |
||
58 | rest = arg%div; |
||
59 | |||
60 | if(rest>0) |
||
61 | { |
||
62 | tmp = (div-rest)*(s32)c_sin_8192(angle); |
||
63 | tmp += rest * (s32)c_sin_8192(angle+1); |
||
64 | tmp /= div; |
||
65 | return(tmp); |
||
66 | } |
||
67 | else if(rest<0) |
||
68 | { |
||
69 | tmp = (div+rest)*(s32)c_sin_8192(angle); |
||
70 | tmp -= rest * (s32)c_sin_8192(angle-1); |
||
71 | tmp /= div; |
||
72 | return(tmp); |
||
73 | } |
||
74 | else |
||
75 | { |
||
76 | return(c_sin_8192(angle)); |
||
77 | } |
||
78 | |||
79 | } |
||
80 | |||
81 | s16 c_cos_8192_res(s16 arg, s16 div) |
||
82 | { |
||
83 | return(c_sin_8192_res(90*div - arg, div)); |
||
84 | } |
||
85 | |||
86 | |||
256 | killagreg | 87 | // integer based atan2 that returns angle in counts of 1/546.13° |
293 | killagreg | 88 | s32 c_atan2_546(s32 y, s32 x) |
256 | killagreg | 89 | { |
90 | s32 qx, qy, q; |
||
91 | |||
92 | if( x < 0) qx = -x; |
||
93 | else qx = x; |
||
94 | if( y < 0) qy = -y; |
||
95 | else qy = y; |
||
96 | if(qy <= qx) |
||
97 | { // scale down to avoid overflow in quadratic interpolation |
||
98 | while(qy > (1<<15)) |
||
99 | { |
||
100 | qy/=2; |
||
101 | qx/=2; |
||
102 | } |
||
103 | // calculate the quatratic interpolation |
||
104 | q = (((qy<<13)/qx)*qy)/qx; |
||
105 | q = (qy<<15)/qx-q; |
||
106 | } |
||
107 | else |
||
108 | { // scale down to avoid overflow in quadratic interpolation |
||
109 | while(qx>(1<<15)) |
||
110 | { |
||
111 | qy/=2; |
||
112 | qx/=2; |
||
113 | } |
||
114 | // calculate the quatratic interpolation |
||
115 | q = (((qx<<13)/qy)*qx)/qy; |
||
116 | q = (qx<<15)/qy-q; |
||
117 | q = 2*((1<<15)-(1<<13)) - q; |
||
118 | } |
||
119 | if(y < 0) |
||
120 | { |
||
121 | if(x < 0) q = q - 4*((1<<15)-(1<<13)); |
||
122 | else q = -q; |
||
123 | } |
||
124 | else if( x < 0) q = 4*((1<<15)-(1<<13)) - q; |
||
125 | return(q); |
||
126 | } |
||
492 | killagreg | 127 | |
128 | |||
129 | |||
130 | // retuns the largest integer whose square is less than or equal to the |
||
131 | u32 isqrt(u32 value) |
||
132 | { |
||
133 | u32 rem = 0, root =0, idx; |
||
134 | |||
135 | for(idx = 0; idx < 16; idx++) |
||
136 | { |
||
137 | root <<= 1; |
||
138 | |||
139 | rem = ((rem << 2) + (value >> 30)); |
||
140 | value <<= 2; |
||
141 | root++; |
||
142 | if(root <= rem) |
||
143 | { |
||
144 | rem -= root; |
||
145 | root++; |
||
146 | } |
||
147 | else |
||
148 | { |
||
149 | root--; |
||
150 | } |
||
151 | } |
||
152 | return(root >> 1); |
||
153 | } |