MOCCA-TP3-2020: cercle.c

File cercle.c, 2.8 KB (added by franck, 4 years ago)

specification c de cordic

Line 
1//-----------------------------------------------------------------------------
2// Calcul des points d'un cercle par l'algorithme Cordic
3//-----------------------------------------------------------------------------
4// cossin :  utilisation des fonctions cos et sin de la bibliothÚque maths
5// cordic :  cordic en virgule fixe 7 chiffres aprÚs la virgules
6//-----------------------------------------------------------------------------
7#include <stdio.h>
8#include <math.h>
9
10#ifndef M_PI
11#define M_PI 3.14159265358979323846
12#endif
13
14void cossin(double a_p, char x_p, char y_p, char *nx_p, char *ny_p)
15{
16    *nx_p = (char) round(x_p * cos(a_p) - y_p * sin(a_p));
17    *ny_p = (char) round(x_p * sin(a_p) + y_p * cos(a_p));
18}
19
20short F_PI = (short)((M_PI) * (1<< 7));
21short ATAN[8] = {
22    0x65,                 // ATAN(2^-0)
23    0x3B,                 // ATAN(2^-1)
24    0x1F,                 // ATAN(2^-2)
25    0x10,                 // ATAN(2^-3)
26    0x08,                 // ATAN(2^-4)
27    0x04,                 // ATAN(2^-5)
28    0x02,                 // ATAN(2^-6)
29    0x01,                 // ATAN(2^-7)
30};
31
32void cordic(short a_p, char x_p, char y_p, char *nx_p, char *ny_p)
33{
34    unsigned char i, q;
35    short a, x, y, dx, dy;   
36   
37    // conversion en virgule fixe : 7 chiffres aprÚs la virgule
38    a = a_p;
39    x = x_p << 7;         
40    y = y_p << 7;
41
42    // normalisalion de l'angle pour être dans le premier quadrant
43    q = 0; 
44    while (a >= F_PI/2) {
45        a = a - F_PI/2; 
46        q = (q + 1) & 3;
47    }
48
49    // rotation
50    for (i = 0; i <= 7; i++) {
51        dx = x >> i;
52        dy = y >> i;
53        if (a >= 0) {
54            x -= dy;
55            y += dx;
56            a -= ATAN[i];
57        } else {
58            x += dy;
59            y -= dx;
60            a += ATAN[i];
61        }
62    }
63
64    // produit du résultat par les cosinus des angles : K=0x4E=1001110
65    x = ((x>>6) + (x>>5) + (x>>4) + (x>>1))>>7;
66    y = ((y>>6) + (y>>5) + (y>>4) + (y>>1))>>7;
67   
68    // placement du points dans le quadrant d'origine
69    switch (q) {
70    case 0:
71        dx = x;
72        dy = y;
73        break;
74    case 1:
75        dx = -y;
76        dy = x;
77        break;
78    case 2:
79        dx = -x;
80        dy = -y;
81        break;
82    case 3:
83        dx = y;
84        dy = -x;
85        break;
86    }
87    *nx_p = dx;
88    *ny_p = dy;
89}
90
91int main()
92{
93    FILE *f;
94
95    f = fopen("cossin.dat", "w");
96    for (double a = 0; a <= M_PI * 2; a += 1. / 64) {
97        char nx_p;
98        char ny_p;
99        cossin(a, 127, 0, &nx_p, &ny_p);
100        fprintf(f, "%4d %4d\n", nx_p, ny_p);
101    }
102    fclose(f);
103
104    f = fopen("cordic.dat", "w");
105    for (short a = 0; a <= 2 * F_PI ; a += 1) {
106        char nx_p;
107        char ny_p;
108        cordic(a, 127, 0, &nx_p, &ny_p);
109        fprintf(f, "%4d %4d\n", nx_p, ny_p);
110    }
111    fclose(f);
112
113    return 0;
114}