Subversion Repositories NaviCtrl

Rev

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
}