我们假设点(x1,y1)与X轴正半轴夹角为α,那么
{ y 2 = s i n ( α + θ ) x 2 = c o s ( α + θ ) \begin{cases} y_2=sin(α+θ)\\ x_2=cos(α+θ) \end{cases} {y2=sin(α+θ)x2=cos(α+θ)
三角函数睁开有
{ y 2 = s i n ( α ) c o s ( θ ) + c o s ( α ) s i n ( θ ) x 2 = c o s ( α ) c o s ( θ ) − s i n ( α ) s i n ( θ ) \begin{cases} y_2=sin(α)cos(θ)+cos(α)sin(θ)\\ x_2=cos(α)cos(θ)-sin(α)sin(θ) \end{cases} {y2=sin(α)cos(θ)+cos(α)sin(θ)x2=cos(α)cos(θ)−sin(α)sin(θ)
将
{ y 1 = s i n ( α ) x 1 = c o s ( α ) \begin{cases} y_1=sin(α)\\ x_1=cos(α) \end{cases} {y1=sin(α)x1=cos(α)
带入上式,有
{ y 2 = s i n ( α ) c o s ( θ ) + c o s ( α ) s i n ( θ ) = y 1 c o s ( θ ) + x 1 s i n ( θ ) = c o s ( θ ) ( y 1 + x 1 t a n ( θ ) ) x 2 = c o s ( α ) c o s ( θ ) − s i n ( α ) s i n ( θ ) = x 1 c o s ( θ ) − y 1 s i n ( θ ) = c o s ( θ ) ( x 1 − y 1 t a n ( θ ) ) \begin{cases} y_2=sin(α)cos(θ)+cos(α)sin(θ)=y_1cos(θ)+x_1sin(θ)=cos(θ)(y_1+x_1tan(θ))\\ x_2=cos(α)cos(θ)-sin(α)sin(θ)=x_1cos(θ)-y_1sin(θ)=cos(θ)(x_1-y_1tan(θ)) \end{cases} {y2=sin(α)cos(θ)+cos(α)sin(θ)=y1cos(θ)+x1sin(θ)=cos(θ)(y1+x1tan(θ))x2=cos(α)cos(θ)−sin(α)sin(θ)=x1cos(θ)−y1sin(θ)=cos(θ)(x1−y1tan(θ))
默认初始值为(1,0),记为
v 0 = [ 1 0 ] v_0=\begin{bmatrix} 1\\ 0 \end{bmatrix} v0=[10]
以上的等式可以表示为旋转矩阵的情势
[ x 2 y 2 ] = c o s ( α ) [ 1 − t a n ( α ) t a n ( α ) 1 ] [ x 1 y 1 ] \begin{bmatrix} x_2\\ y_2 \end{bmatrix} =cos(α) \begin{bmatrix} 1 & -tan(α)\\ tan(α)&1 \end{bmatrix} \begin{bmatrix} x_1\\ y_1 \end{bmatrix} [x2y2]=cos(α)[1tan(α)−tan(α)1][x1y1]
如果将令角度α,满意tan(α)=2-i, 那么就将tan和乘法运算就变成乘2的负次幂。对应在计算机中,就是移位计算。因而复杂的计算,就变成了简单的加减和移位运算。
以是我们有
[ x n y n ] = c o s ( α n ) [ 1 − 2 − n 2 − n 1 ] [ x n − 1 y n − 1 ] = c o s ( α n ) c o s ( α n − 1 ) . . c o s ( α 0 ) [ 1 − 2 − n 2 − n 1 ] [ 1 − 2 − n + 1 2 − n + 1 1 ] . . [ 1 − 2 − 0 2 − 0 1 ] [ 1 0 ] \begin{bmatrix} x_n\\ y_n \end{bmatrix} =cos(α_n) \begin{bmatrix} 1 & -2^{-n}\\ 2^{-n}&1 \end{bmatrix} \begin{bmatrix} x_{n-1}\\ y_{n-1} \end{bmatrix}= cos(α_n)cos(α_{n-1})..cos(α_0) \begin{bmatrix} 1 & -2^{-n}\\ 2^{-n}&1 \end{bmatrix} \begin{bmatrix} 1 & -2^{-n+1}\\ 2^{-n+1}&1 \end{bmatrix} .. \begin{bmatrix} 1 & -2^{-0}\\ 2^{-0}&1 \end{bmatrix} \begin{bmatrix} 1\\ 0 \end{bmatrix} [xnyn]=cos(αn)[12−n−2−n1][xn−1yn−1]=cos(αn)cos(αn−1)..cos(α0)[12−n−2−n1][12−n+1−2−n+11]..[12−0−2−01][10]
处置惩罚细节
1. 缩放因子
由前面推导,我们可以得到:
[ x n y n ] = c o s ( α n ) [ 1 − 2 − n 2 − n 1 ] [ x n − 1 y n − 1 ] = c o s ( α n ) c o s ( α n − 1 ) . . c o s ( α 0 ) [ 1 − 2 − n 2 − n 1 ] [ 1 − 2 − n + 1 2 − n + 1 1 ] . . [ 1 − 2 − 0 2 − 0 1 ] [ 1 0 ] \begin{bmatrix} x_n\\ y_n \end{bmatrix} =cos(α_n) \begin{bmatrix} 1 & -2^{-n}\\ 2^{-n}&1 \end{bmatrix} \begin{bmatrix} x_{n-1}\\ y_{n-1} \end{bmatrix}= cos(α_n)cos(α_{n-1})..cos(α_0) \begin{bmatrix} 1 & -2^{-n}\\ 2^{-n}&1 \end{bmatrix} \begin{bmatrix} 1 & -2^{-n+1}\\ 2^{-n+1}&1 \end{bmatrix} .. \begin{bmatrix} 1 & -2^{-0}\\ 2^{-0}&1 \end{bmatrix} \begin{bmatrix} 1\\ 0 \end{bmatrix} [xnyn]=cos(αn)[12−n−2−n1][xn−1yn−1]=cos(αn)cos(αn−1)..cos(α0)[12−n−2−n1][12−n+1−2−n+11]..[12−0−2−01][10]
我们可以提前将所有的cos(α)的乘积计算出来,做为一个常量,省去乘法运算,记为K
K = c o s ( α n ) c o s ( α n − 1 ) c o s ( α n − 2 ) . . . c o s ( α 0 ) = 0.60725 K=cos(α_n)cos(α_{n-1})cos(α_{n-2})...cos(α_0)=0.60725 K=cos(αn)cos(αn−1)cos(αn−2)...cos(α0)=0.60725 2. 旋转方向
通常来说CORDIC算法会引入dn ,来判断旋转方向。当前角度大于该次迭代的角度,dn为正,逆时钟旋转,反之为负,顺时针旋转。之以是会采用双旋转,是因为其通常比单向旋转的收敛性更好,结果更精确。
因而我们迭代可以写为
{ y n + 1 = y n + d n ∗ x n ∗ 2 − n x n + 1 = x n − d ∗ y n ∗ 2 − n a n g l e n + 1 = a n g l e n − d ∗ t a b l e o f a n g l e s [ n ] \begin{cases} y_{n+1}=y_n+d_n*x_n*2^{-n}\\ x_{n+1}=x_n-d*y_n*2^{-n}\\ angle_{n+1}=angle_{n}-d*tableofangles[n] \end{cases} ⎩ ⎨ ⎧yn+1=yn+dn∗xn∗2−nxn+1=xn−d∗yn∗2−nanglen+1=anglen−d∗tableofangles[n]
table_of_angles 存储的是θ值, θn=arctan(2-n);
对应的表格如下:
n2^(-n)arctan(2^(-n))010.78539816310.50.46364760920.250.24497866330.1250.12435499540.06250.0624188150.03150.03123983360.0156250.01562372970.00781250.00781234180.003906250.0039062390.0019531250.001953123100.0009765630.000976562110.0004882810.000488281120.0002441410.000244141130.000122070.00012207146.10352E-056.10352E-05153.05176E-053.05176E-05 下面我会手把手领导大家从软件建模到硬件实现CORDIC算法,规定输入和输出都是无符号17位数,1位整数位,16位小数位。
Python 代码