ESP8266 ILI9341 display support code with printf sources, wire-frame viewer and custom fonts  1.0
ESP8266ILI9341DisplayProject
cordic.c
Go to the documentation of this file.
1 
32 // Run a standalone test
33 // #define TEST
34 
35 #define CORDIC_TABLE /* include the generated Cordic table */
36 
37 #ifdef TEST
38 #define MEMSPACE /* */
39 #include <stdio.h>
40 #include <stdlib.h>
41 #else
42 #include "user_config.h"
43 #include <stdint.h>
44 #include <string.h>
45 #include "printf/mathio.h"
46 #endif
47 
48 #include <math.h>
49 
50 #include "cordic2c_inc.h"
51 #include "cordic.h"
52 
57 double deg2rad(double deg)
58 {
59  return (deg * M_PI / 180.0);
60 }
61 
71 double angle_quad(double quads, int *quad)
72 {
73 
74  int s,q;
75  double intpart;
76 
77  s = 0;
78  if(quads < 0.0)
79  {
80  quads = -quads;
81  s = 4; // sign information flag
82  }
83 
84  quads = modf(quads, &intpart);
85  q = intpart;
86  q &= 3;
87  q |= s;
88  *quad = q;
89  return(quads);
90 
91 }
92 
93 
104 {
105  int i;
106 
107  X = x;
108  Y = y;
109  Z = z;
110 
111  for (i = 0; i < Cordic_T_Bits; ++i)
112  {
113  x = X >> i;
114  y = Y >> i;
115 
116  if(i < 14)
117  z = v_atangrad[i];
118  else
119  z >>= 1;
120 
121  if(Z >= 0)
122  {
123  X -= y;
124  Y += x;
125  Z -= z;
126  }
127  else
128  {
129  X += y;
130  Y -= x;
131  Z += z;
132  }
133  }
134 }
135 
136 
143 MEMSPACE
144 void cordic_quad(double angle, double *s, double *c)
145 {
146 #ifdef TEST
147  double ts,tc;
148  double es,ec;
149  double degree, rad, orig;
150 #endif
151 
152  double cs,cc;
153  double quads, tmp;
154  int quad;
155  Cordic_T a;
156 
157  quads = angle_quad(angle,&quad);
158 
159  a = FP2Cordic(quads); /* convert to CORDIC fixed point */
160  Circular(Cordic_K,0,a);
161  cc = Cordic2FP(X);
162  cs = Cordic2FP(Y);
163 
164 // Angle 90 to < 180 degrees swap sin and cos, and negate cos
165  if(quad & 1)
166  {
167  tmp = cc;
168  cc = cs;
169  cs = tmp;
170  cc = -cc;
171  }
172 
173 // Angle 180 >.. 270 degrees negate both cos and sin
174  if(quad & 2 )
175  {
176  cs = -cs;
177  cc = -cc;
178  }
179 // Angle < 0 degrees negate only sin
180  if(quad & 4 )
181  {
182  cs = -cs;
183  }
184 
185  *c = cc;
186  *s = cs;
187 
188 // Test difference between CORDIC and LIBC cos() and sin()
189 #ifdef TEST
190  degree = angle * 90;
191  rad = angle * M_PI / 2.0;
192  tc = cos(rad);
193  ts = sin(rad);
194 
195  ec = cc - tc;
196  es = cs - ts;
197  printf("Degree:%lf, rad:%lf, quad:%d\n",
198  (double)angle, (double) rad, (int)quad);
199  printf("ccos:%lf, cos:%lf, error:%lf\n",
200  cc, tc, ec);
201  printf("csin:%lf, sin:%lf, error:%lf\n",
202  cs, ts, es);
203 #endif
204 
205 }
206 
207 
214 MEMSPACE
215 void cordic_deg(double deg, double *s, double *c)
216 {
217  cordic_quad(deg/90.0, s, c);
218 }
219 
220 
227 MEMSPACE
228 void cordic_rad(double rad, double *s, double *c)
229 {
230  cordic_quad(rad * 2.0 /M_PI, s, c);
231 }
232 
233 
238 MEMSPACE
239 void scale_point(point *P, double scale)
240 {
241  P->x *= scale;
242  P->y *= scale;
243  P->z *= scale;
244 }
245 
246 
251 MEMSPACE
252 void shift_point(point *P, point *shift)
253 {
254  P->x += shift->x;
255  P->y += shift->y;
256  P->z += shift->x;
257 }
258 
259 
264 MEMSPACE
265 void rotate(point *P, point *V)
266 {
267  double sinx, siny, sinz, cosx, cosy, cosz;
268  double x,y,z,x1,y1,z1;
269 
270 // Point
271  x = P->x;
272  y = P->y;
273  z = P->z;
274 
275 // Transform Point
276 
277 // View is in degrees
278  cordic_deg(V->x, &sinx, &cosx);
279  cordic_deg(V->y, &siny, &cosy);
280  cordic_deg(V->z, &sinz, &cosz);
281 
282  x1 = x*cosz + y*sinz; // Rotation around axis Z
283  y1 = -x*sinz + y*cosz;
284  z1 = z;
285 
286  x = x1; // Rotation around axis X
287  y = y1*cosx + z1*sinx;
288  z = -y1*sinx + z1*cosx;
289 
290  x1 = x*cosy - z*siny; // Rotation around axis Y
291  y1 = y;
292  z1 = x*siny + z*cosy;
293 
294 // Transformed point
295  P->x = x1;
296  P->y = y1;
297  P->z = z1;
298 }
299 
300 
301 /*
302  @brief // Perspective Projection with Offset and Scale
303  @param[in] *P: x,y,z point, out: x,y ( z = 0 )
304  @param [in] scale: scale factor
305  @param [out] x: X offset
306  @param [out] y: Y offset
307  @return void
308 */
309 MEMSPACE
310 void PerspectiveProjection(point *P, double scale, int x, int y)
311 {
312  P->x = (P->x + P->z / 2) * scale + x;
313  P->y = (P->y - P->z / 2) * scale + y;
314  P->z = 0;
315 }
316 
317 #ifdef TEST
318 int main()
321 {
322  double d;
323  double s,c;
324  int i;
325 
326  i = 0;
327 
328 // Make sure CORIC converges correctly over a few rotations
329  for(d=0;d<=360;d+=45)
330  {
331  cordic_deg(d-1,&s,&c);
332  cordic_deg(d,&s,&c);
333  cordic_deg(d+1,&s,&c);
334  }
335  return(0);
336 }
337 #endif
338 
Master include file for project Includes all project includes and defines here.
MEMSPACE void shift_point(point *P, point *shift)
Shift x,y,z by shift.
Definition: cordic.c:252
Cordic_T X
Main Cordic routine - used for basic trig and vector rotations We use fixed point numbers...
Definition: cordic.c:102
MEMSPACE double deg2rad(double deg)
Convert Degrees to Rads.
Definition: cordic.c:57
MEMSPACE void cordic_deg(double deg, double *s, double *c)
Compute Sin and Cos from angle in degrees using Cordic.
Definition: cordic.c:215
int16_t y[XYSTACK+2]
Definition: ili9341.c:372
Cordic_T Y
Definition: cordic.c:102
#define Cordic2FP(a)
Definition: cordic2c_inc.h:20
MEMSPACE void cordic_rad(double rad, double *s, double *c)
Compute Sin and Cos from angle in Rads using Cordic.
Definition: cordic.c:228
int16_t x[XYSTACK+2]
Definition: ili9341.c:371
#define FP2Cordic(a)
Definition: cordic2c_inc.h:21
MEMSPACE void PerspectiveProjection(point *P, double scale, int x, int y)
Definition: cordic.c:310
double y
Definition: cordic.h:40
Cordic Routines Handle angle outside of the first quadrant Added standalone test to verify CORDIC aga...
int Cordic_T
Definition: cordic2c_inc.h:9
Cordic_T Z
Definition: cordic.c:102
MEMSPACE void scale_point(point *P, double scale)
Scale x,y,z by scale factor.
Definition: cordic.c:239
int main(int argc, char *argv[])
Definition: send.c:148
const Cordic_T v_atangrad[]
Math IO functions, and verious conversion code with floating point support.
double x
Definition: cordic.h:39
Point definition.
Definition: cordic.h:37
#define MEMSPACE
Definition: cpu.h:25
MEMSPACE int printf(const char *format,...)
MEMSPACE void cordic_quad(double angle, double *s, double *c)
Compute Sin and Cos from angle in quads using Cordic.
Definition: cordic.c:144
MEMSPACE double angle_quad(double quads, int *quad)
Compute quadrant of angle and the quadrant modulus Note: Integer part is quadrant.
Definition: cordic.c:71
#define Cordic_K
Definition: cordic2c_inc.h:15
double z
Definition: cordic.h:41
void Circular(Cordic_T x, Cordic_T y, Cordic_T z)
Definition: cordic.c:103
#define Cordic_T_Bits
Definition: cordic2c_inc.h:12
MEMSPACE void rotate(point *P, point *V)
Rotate point P by View point.
Definition: cordic.c:265