快速算法 之 CORDIC算法 坐标转换
功能: 直角坐标 转换为极坐标
原理: 利用角度旋转与查找来进行快速计算....大家可以参考:
http://doc.baidu.com/view/9b70ff64783e0912a2162a5c.html
我的文笔不好,实在没法子写那样多! 还是代码来的好!
上代码吧:
#define MAX_ITERATION (13)
double cordic_scale[13] = { 1,
0.5,
0.25,
0.125,
0.0625,
0.03125,
0.015625,
0.0078125,
0.00390625,
0.001953125,
0.000976463,
0.000488281,
0.000244141
};
int cordic_ang_i[13] = { 46080,// 45.0000000000,
27203,// 26.5650511771,
14373,// 14.0362434679,
7296,// 7.1250163489,
3662,// 3.5763343750,
1833,// 1.7899106082,
917,// 0.8951737102,
458,// 0.4476141709,
229,// 0.2238105004,
115,// 0.1119056771,
57,// 0.0559528919,
29,// 0.0279764526,
14// 0.0139882271
};
double cordic_ang_d[13] ={45.0000000000,
26.5650511771,
14.0362434679,
7.1250163489,
3.5763343750,
1.7899106082,
0.8951737102,
0.4476141709,
0.2238105004,
0.1119056771,
0.0559528919,
0.0279764526,
0.0139882271
};
void cordic_int_core(int &oldX,int &oldY,int &z,int depth)
{
int d;
if (oldY>=0)
{
d = -1;
}
else
{
d = +1;
}
int newX;
int newY;
if (d>0)
{
//newX = oldX - oldY*cordic_scale[depth];
//newY = oldY + oldX*cordic_scale[depth];
newX = oldX - (oldY>>depth);
newY = oldY + (oldX>>depth);
z = z - cordic_ang_i[depth];
}
if (d<0)
{
newX = oldX + (oldY>>depth);
newY = oldY - (oldX>>depth);
z = z + cordic_ang_i[depth];
}
oldX = newX;
oldY = newY;
}
void cordic_double_core(double &oldX,double &oldY,double &z, int depth )
{
int d;
if (oldY>=0)
{
d = -1;
}
else
{
d = +1;
}
double newX;
double newY;
if (d>0)
{
newX = oldX - oldY*cordic_scale[depth];
newY = oldY + oldX*cordic_scale[depth];
z = z - cordic_ang_d[depth];
}
if (d<0)
{
newX = oldX + oldY*cordic_scale[depth];
newY = oldY - oldX*cordic_scale[depth];
z = z + cordic_ang_d[depth];
}
oldX = newX;
oldY = newY;
}
void cordic_int(int x, int y, double &R, double &A, int size )
{
x=x<<size;
y=y<<size;
int Angle = 0;
for (int i=0; i<MAX_ITERATION; i++)
{
cordic_int_core(x,y,Angle,i);
}
x=x>>size;
y=y>>size;
R = x*0.607252941; //此处需转化为2的倍数
A = Angle/1024.0;
}
void cordic_double(double x, double y, double &R, double &A )
{
double Angle = 0;
for (int i=0; i<MAX_ITERATION; i++)
{
cordic_double_core(x,y,Angle,i);
}
R = x*0.607252941;
A = Angle;
}
int main(int argc, char* argv[])
{
int x = 10;
int y = 10;
int s = 3;
double zR,zA;
zR = 0.0;
zA = 0.0;
cordic_double(x, y, zR, zA);
printf("double [%12.6f %9.5f] \n", zR, zA);
double R,A;
// for (int i=0; i<10; i++)
{
R = 0.0;
A = 0.0;
// s = i;
cordic_int(x, y, R, A, s);
printf(" int [%12.6f %9.5f] s= %d %9.5f %9.5f\n", R, A, s, (zR - R)/zR, (zA - A)/zA);
}
return 0;
}