2. 圆弧插补基础实现
任务目标
实现二维平面圆弧插补算法,支持顺/逆时针方向,给定圆心、半径、起始角与终止角后,按固定步距角输出插补点序列,并验证所有插补点到圆心的距离与理论半径的误差在允许范围内。
实现方案
采用角度增量法:从起始角开始,按固定步距角逐步累加至终止角,每个角度对应一个插补点。顺逆时针通过角度增减方向区分。核心数据结构为圆弧参数结构体,核心函数为圆弧插补生成器与半径误差验证函数。
关键完整代码
#include <stdio.h>
#include <math.h>
#define PI 3.14159265358979323846
typedef struct {
double cx, cy; // 圆心坐标
double r; // 半径
double start_angle; // 起始角(弧度)
double end_angle; // 终止角(弧度)
int clockwise; // 1=顺时针, 0=逆时针
} ArcParams;
// 圆弧插补:输出插补点,返回点数
int arc_interpolate(ArcParams arc, double step_angle,
double *out_x, double *out_y, int max_points) {
int n = 0;
double angle = arc.start_angle;
double total_angle;
// 计算总角度(考虑跨0°情况)
if (arc.clockwise) {
total_angle = arc.start_angle - arc.end_angle;
if (total_angle < 0) total_angle += 2 * PI;
} else {
total_angle = arc.end_angle - arc.start_angle;
if (total_angle < 0) total_angle += 2 * PI;
}
int steps = (int)ceil(total_angle / step_angle);
if (steps > max_points) steps = max_points;
for (int i = 0; i <= steps && n < max_points; i++) {
double current_angle = angle + (arc.clockwise ? -1 : 1) * i * step_angle;
// 确保不超过终止角
if (arc.clockwise) {
if (current_angle < arc.end_angle - 1e-9) break;
} else {
if (current_angle > arc.end_angle + 1e-9) break;
}
out_x[n] = arc.cx + arc.r * cos(current_angle);
out_y[n] = arc.cy + arc.r * sin(current_angle);
n++;
}
return n;
}
// 验证半径误差:返回最大误差
double verify_radius_error(double *x, double *y, int n,
double cx, double cy, double r) {
double max_err = 0.0;
for (int i = 0; i < n; i++) {
double dist = sqrt((x[i]-cx)*(x[i]-cx) + (y[i]-cy)*(y[i]-cy));
double err = fabs(dist - r);
if (err > max_err) max_err = err;
}
return max_err;
}
int main() {
// 示例:圆心(0,0),半径10,从0°到90°,逆时针,步距角5°
ArcParams arc = {0, 0, 10, 0, PI/2, 0};
double step_angle = 5.0 * PI / 180.0; // 5°
double x[100], y[100];
int n = arc_interpolate(arc, step_angle, x, y, 100);
printf("插补点数: %d\n", n);
for (int i = 0; i < n; i++) {
printf("P%d: (%.4f, %.4f)\n", i, x[i], y[i]);
}
double max_err = verify_radius_error(x, y, n, arc.cx, arc.cy, arc.r);
printf("最大半径误差: %.6f\n", max_err);
// 验证通过条件
if (max_err < 1e-6) {
printf("验证通过:所有插补点半径误差在允许范围内\n");
} else {
printf("验证失败:存在超差插补点\n");
}
return 0;
}
编译与运行
gcc -o arc_interp arc_interp.c -lm
./arc_interp
验证方法
程序输出每个插补点坐标及最大半径误差。判定通过条件:最大半径误差小于1e-6(即浮点计算精度范围内),且插补点数与理论计算一致(90°/5°+1=19个点)。可修改圆弧参数测试顺逆时针、跨0°边界、整圆等场景。
预期输出(示例)
插补点数: 19
P0: (10.0000, 0.0000)
P1: (9.9619, 0.8716)
...
P18: (0.0000, 10.0000)
最大半径误差: 0.000000
验证通过:所有插补点半径误差在允许范围内
说明:上述输出为基于代码逻辑的确定性预期结果,非实测数据。实际运行时浮点舍入可能导致最后一位微小差异,但不影响误差判定。