MOCCA-TP3-2020: cercle.c

File cercle.c, 2.8 KB (added by franck, 6 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}