Cordic算法——圆周系统之向量模式
旋转模式用来解决三角函数,实现极坐标到直角坐标的转换,基础理论请参考Cordic算法——圆周系统之旋转模式。那么,向量模式则用来解决反三角函数的问题,体现的应用主要是直角坐标向极坐标转换,即已知一点的直角坐标(x,y),求其极坐标(α,γ),实际上是求arctan(y/x)。
旋转模式下,每次迭代使z趋近于α(α-z趋近于0),而向量模式下,则使y趋近于0,这一点很好理解,即从坐标位置,旋转到x正半轴,一共旋转了多少角度,则该角度即为α,从而知道了极角。

如图所示,在单位圆上,向量OP与X轴的正半轴夹角为α,故P点的坐标可表示为

根据开头描述,我们需要转动向量OP,先顺时针旋转θ角至向量OQ,Q点的坐标可表示为

这里定义θ为目标旋转角度。根据三角函数公式可将上式展开为

现在已经有点 Cordic 算法的样子了,但是我们看到每次旋转都要计算 4 次浮点数的乘法运算,运算量还是太大了。还需要进一步的改进,改进的切入点当然还是坐标变换的过程。
将式(1.1)代入到式(1.3)中可得

用矩阵形式表示为:

旋转了i次以后,可以得到:

最终需将y_Q_i+1转为0,先按45°的二分法查找来解释过程,用C语言描述过程为:
#include <stdio.h>
#include <stdlib.h>
double cordic_v(double x, double y);
int main(viod)
{
double alfa = cordic_v(120.0,200.0); //直角坐标(x,y)
printf("\n 极角为 = %f \n",alfa);
return 0;
}
double cordic_v(double x, double y)
{
const double sine[] = {0.7071067811865,0.3826834323651,0.1950903220161,
0.09801714032956,0.04906767432742,0.02454122852291,0.01227153828572,
0.006135884649154,0.003067956762966,0.001533980186285,
7.669903187427045e-4,3.834951875713956e-4,1.917475973107033e-4,
9.587379909597735e-5,4.793689960306688e-5,2.396844980841822e-5
};
const double cosine[] = {0.7071067811865,0.9238795325113,0.9807852804032,0.9951847266722,
0.9987954562052,0.9996988186962,0.9999247018391,0.9999811752826,0.9999952938096,
0.9999988234517,0.9999997058629,0.9999999264657,0.9999999816164,0.9999999954041,
0.999999998851,0.9999999997128
};
int i = 0;
double x_new, y_new;
double angleSum = 0.0;
double angle = 45.0; //第一次旋转角度为45°
for( i=0; i<15;i++)
{
if(y > 0)
{
x_new = x * cosine[i] + y * sine[i];
y_new = y * cosine[i] - x * sine[i];
x = x_new;
y = y_new;
angleSum += angle;
}
else
{
x_new = x * cosine[i] - y * sine[i];
y_new = y * cosine[i] + x * sine[i];
x = x_new;
y = y_new;
angleSum -= angle;
}
printf("旋转次数: i = %2d 旋转角度 = %10f, 累计旋转角度 = %10f\n", i+1, angle,angleSum );
angle /= 2;
}
return angleSum;
}

经过旋转模式的推导,向量模式的伪旋转公式,可表示为

C语言描述过程,如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double cordic_v(double x, double y);
double r = 0.0; //定义一个模长全局变量
int main(viod)
{
double alfa = cordic_v(120.0,200.0); //直角坐标(x,y)
printf("\n极角 = %5f, 模长 = %5f\n",alfa,r);
return 0;
}
double cordic_v(double x, double y)
{
const double theta[] = { 45.0, 26.56505118, 14.03624347, 7.125016349,
3.576334375, 1.789910608, 0.8951737102, 0.4476141709,
0.2238105004, 0.1119056771, 0.05595289189, 0.02797645262,
0.01398822714, 0.006994113675, 0.003497056851, 0.001748528427
}; //旋转角度
int i = 0;
double x_new, y_new;
double angleSum = 0.0;
r = sqrt(x*x+y*y);
for( i=0; i<16;i++)
{
if(y > 0)
{
x_new = x + y/(1<<i);
y_new = y - x/(1<<i);
x = x_new;
y = y_new;
angleSum += theta[i];
}
else
{
x_new = x - y/(1<<i);
y_new = y + x/(1<<i);
x = x_new;
y = y_new;
angleSum -= theta[i];
}
printf("旋转次数: i = %2d 旋转角度 = %10f, 累计旋转角度 = %10f, y = %5f\n", i+1,theta[i],angleSum,y );
}
return angleSum;
}

同样,向量模式的cordic算法适用于第一、四象限的坐标变换,在第二、三象限的坐标需要进行预处理。
参考
《基于FPGA的数字信号处理(第2版)》——高亚军著
Cordic算法——圆周系统之向量模式的更多相关文章
- FPGA算法学习(1) -- Cordic(圆周系统之向量模式)
旋转模式用来解决三角函数,实现极坐标到直角坐标的转换,基础理论请参考Cordic算法--圆周系统之旋转模式.那么,向量模式则用来解决反三角函数的问题,体现的应用主要是直角坐标向极坐标转换,即已知一点的 ...
- Cordic算法——圆周系统之旋转模式
三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...
- FPGA算法学习(1) -- Cordic(圆周系统之旋转模式)
三角函数的计算是个复杂的主题,有计算机之前,人们通常通过查找三角函数表来计算任意角度的三角函数的值.这种表格在人们刚刚产生三角函数的概念的时候就已经有了,它们通常是通过从已知值(比如sin(π/2)= ...
- Cordic算法——verilog实现
上两篇博文Cordic算法--圆周系统之旋转模式.Cordic算法--圆周系统之向量模式做了理论分析和实现,但是所用到的变量依然是浮点型,而cordic真正的用处是基于FPGA等只能处理定点的平台.只 ...
- 使用CORDIC算法求解角度正余弦及Verilog实现
本文是用于记录在了解和学习CORDIC算法期间的收获,以供日后自己及他人参考:并且附上了使用Verilog实现CORDIC算法求解角度的正弦和余弦的代码.简单的testbench测试代码.以及在Mod ...
- cordic算法的verilog实现及modelsim仿真
1. 算法介绍 CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲 ...
- CORDIC算法(1):圆周旋转模式下计算三角函数和模值
CORDIC(Coordinate Rotation Digital Computer)坐标旋转数字计算机,是数学与计算机技术交叉产生的一种机器算法,用于解决计算机的数学计算问题.发展到现在,CORD ...
- 基于FPGA的cordic算法的verilog初步实现
最近在看cordic算法,由于还不会使用matlab,真是痛苦,一系列的笔算才大概明白了这个算法是怎么回事.于是尝试用verilog来实现.用verilog实现之前先参考软件的程序,于是先看了此博文h ...
- 基于FPGA的Cordic算法实现
CORDIC(Coordinate Rotation Digital Computer)算法即坐标旋转数字计算方法,是J.D.Volder1于1959年首次提出,主要用于三角函数.双曲线.指数.对数的 ...
随机推荐
- JS在可编辑的div中的光标位置插入内容或表情
<input type="button" value="插入字符" onclick="document.getElementById('test ...
- web前端上传图片的几种方法
1.表单上传 最传统的图片上传方式是form表单上传,使用form表单的input[type=”file”]控件,打开系统的文件选择对话框,从而达到选择文件并上传的目的. form表单上传 表单上传需 ...
- CSS之 absoulte 属性
特性: absoulte 与 float 具有相同的特性:包裹性,与破坏性 absoulte 与 float 可以交替使用 不受 relative 限制的 absoulte 定位,行为表现上可以不 ...
- Fatal error in launcher:Unable to create process using '"'
Windows下同时存在Python2和Python3使用pip时系统报错:Fatal error in launcher: Unable to create process using '" ...
- Python学习笔记(七)
Python学习笔记(七): 深浅拷贝 Set-集合 函数 1. 深浅拷贝 1. 浅拷贝-多层嵌套只拷贝第一层 a = [[1,2],3,4] b = a.copy() print(b) # 结果:[ ...
- Android基础知识05—活动的生命周期
------ 活动的生命周期 ------ Android是使用任务Task来管理活动的,一个任务就是一组存放在栈里的活动的集合.每当启动一个活动 ,他就会在返回栈中入栈,并处于栈顶位置.而每当我们按 ...
- PHP中foreach()用法汇总
这篇文章主要给大家详细介绍了PHP中foreach()用法以及相关的示例,十分的细致,有需要的小伙伴可以参考下. PHP 4 引入了 foreach 结构,和 Perl 以及其他语言很像.这只是一种遍 ...
- C语言第一次实验报告
一.实验题目,设计思路,实现方法 7-7 计算火车运行时间(15 分) 4-5 求简单交错序列前N项和(15 分) 4-2-7 装睡(10 分) 思路:7-7须将时间统一单位,化为以分钟计算再将两者相 ...
- ELK系列~log4-nxlog-Fluentd-elasticsearch写json数据需要注意的几点
经验与实践 前两篇文章里我们介绍了nxlog的日志收集和转发<ELK系列~Nxlog日志收集加转发(解决log4日志换行导致json转换失败问题)>,今天我们主要总结一下,在与log4和f ...
- HiveQL简单操作DDL
hive-2.1.1 DDL操作 Create/Drop/Alter/Use Database 创建数据库 //官方指导 CREATE (DATABASE|SCHEMA) [IF NOT EXISTS ...