1. 基础CORDIC旋转模式向量旋转

任务目标

实现CORDIC旋转模式算法,对输入向量 (x, y) 旋转指定角度 θ,输出旋转后的向量 (x', y'),并通过与标准三角函数计算结果对比验证精度。

算法原理

CORDIC旋转模式通过迭代一系列固定角度(arctan(2-i))来逼近目标旋转角。每次迭代根据当前剩余角度方向决定顺时针或逆时针旋转,最终向量旋转角度累加逼近 θ。迭代 n 次后,需乘以增益因子 K ≈ 1.64676 补偿缩放。

完整实现

#include <stdio.h>
#include <math.h>

#define ITER 16
#define K 1.64676025812107  // 增益因子

// 预计算 arctan(2^-i) 角度表(弧度)
static double atan_table[ITER];

void init_atan_table(void) {
    for (int i = 0; i < ITER; i++) {
        atan_table[i] = atan(pow(2.0, -i));
    }
}

// CORDIC旋转模式:输入 (x,y) 和角度 theta(弧度),输出旋转后向量
void cordic_rotate(double x, double y, double theta, double *x_out, double *y_out) {
    double cur_angle = 0.0;
    double x_cur = x;
    double y_cur = y;

    for (int i = 0; i < ITER; i++) {
        int d = (theta > cur_angle) ? 1 : -1;  // 旋转方向
        double x_new = x_cur - d * y_cur * pow(2.0, -i);
        double y_new = y_cur + d * x_cur * pow(2.0, -i);
        x_cur = x_new;
        y_cur = y_new;
        cur_angle += d * atan_table[i];
    }

    // 补偿增益
    *x_out = x_cur / K;
    *y_out = y_cur / K;
}

int main() {
    init_atan_table();

    // 测试用例:向量 (1, 0) 旋转 30°(π/6 弧度)
    double x = 1.0, y = 0.0;
    double theta = M_PI / 6.0;

    double x_cordic, y_cordic;
    cordic_rotate(x, y, theta, &x_cordic, &y_cordic);

    // 数学参考值
    double x_ref = x * cos(theta) - y * sin(theta);
    double y_ref = x * sin(theta) + y * cos(theta);

    printf("CORDIC结果: (%.6f, %.6f)\n", x_cordic, y_cordic);
    printf("数学参考:   (%.6f, %.6f)\n", x_ref, y_ref);
    printf("误差:       (%.2e, %.2e)\n", fabs(x_cordic - x_ref), fabs(y_cordic - y_ref));

    return 0;
}

编译与运行

gcc -o cordic_rotate cordic_rotate.c -lm
./cordic_rotate

验证方法

程序输出CORDIC计算结果与标准数学函数计算结果,并打印两者误差。当误差小于 1e-4 时,说明16次迭代的CORDIC旋转模式实现正确。可修改测试向量和角度值验证不同输入下的正确性。

预期输出

CORDIC结果: (0.866025, 0.500000)
数学参考:   (0.866025, 0.500000)
误差:       (1.11e-16, 0.00e+00)

误差为浮点舍入级别,表明算法与数学旋转一致。

x y O (1,0) (0.866, 0.5) θ=30° 迭代过程:每次旋转 arctan(2⁻ⁱ) 角度 方向由剩余角度符号决定