“ 上一篇文章Cordic算法FPGA实现cos,sin讲解了Cordic算法实现sin,cos等函数,本篇讲解Cordic算法实现distance=√(x^2+y^2 ),即根据直角三角形两直角边求斜边边长。”
如果对Cordic算法的核心思想不了解或者想得到更好的理解,可以先阅读上一篇文章“Cordic算法实现sin,cos”。
从上一篇文章,可知Cordic算法其实就是一个循环迭代的思想。
仍然借助上一篇文章的基础,旋转迭代16次,每次迭代的角度如下(为何取这些迭代角度,见“Cordic算法实现sin,cos”):
`define angle0 45.0
`define angle1 26.56505117707799
`define angle2 14.036243467926479
`define angle3 7.125016348901798
`define angle4 3.576334374997351
`define angle5 1.789910608246069
`define angle6 0.895173710211074
`define angle7 0.44761417086055
`define angle8 0.22381050036853
`define angle9 0.11190567706620
`define angle10 0.05595289189380
`define angle11 0.02797645261700
`define angle12 0.01398822714226
`define angle13 0.00699411367535
`define angle14 0.00349705685070
`define angle15 0.00174852842698
根据当(x1,y1)转过θ角之后,到达点(x2,y2),有如下等式关系(根据三角函数的角度加减运算推导一下就出来了)。x2 = rcos(θ0+θ) = x1cosθ-y1sinθ = cosθ(x1 - y1tanθ)
y2 = rsin(θ0+θ) = x1sinθ+y1cosθ = cosθ(y1 + x1tanθ)
在上一篇根据角度求sin,cos值时,我们以旋转的角度作为下次旋转方向的判断,即每次迭代旋转的角度都减半,旋转之后如果大于所要求的角度值,就顺时钟回转,否则逆时钟转动,最终其就会向我们所要求的角度值位置逼近。初始化x=1,y=0,旋转16次后得到的x,y就是对应的cos,sin值。
这次我们是要求distance=√(x^2+y^2 )
,即直角三角形斜边长度。旋转迭代逼近思想如下。
根据两直角边x,y的值确定其初始位置,然后将其向x轴旋转逼近,最终得到的x值就是就是原直线的的长度,即直角边长度,演示视屏如下(初始x=100,y = 400,迭代16次后得到y = 0,x = 412.310562即√(x^2+y^2 ))
。
##01 python软件模型
for i in range(0,16) :
arctan_value[i] = (1/2)**i
angle_e = np.degrees(np.arctan(arctan_value))
cos_e = np.cos(angle_e*np.pi/180)
k = 1
for i in range(0,16):
k = cos_e[i]*k
x = 100
y = 400
angle = 0
x_p1 = np.zeros((17,2))
y_p1 = np.zeros((17,2))
for i in range(0,16):
#get picture of x,y
x_p1[i] = [0,x]
y_p1[i] = [0,y]
if y < 0:
x_h = x - y*arctan_value[i]
y_h = y + x*arctan_value[i]
angle = angle - angle_e[i]
else :
x_h = x + y*arctan_value[i]
y_h = y - x*arctan_value[i]
angle = angle + angle_e[i]
x = x_h
y = y_h
print(angle)
distance = x*k
print(distance)
02 verilog硬件实现
采用16级流水结构。为了避免浮点数的运算,将原始数据都扩大了2^16,不过运算结果distance就是真正的√(x^2+y^2 )。