直线拟合算法
函数说明:
通过一些点拟合出一条直线。
参数:
pt_input
指向传入的点的指针。
ptNumbers
传入的点数量。
k
指向拟合直线参数k的指针。
b
指向拟合直线参数b的指针。
返回值:
返回一个代数值判断拟合是否成功。如果成功,则返回 0。如果返回-1,表示点的数量<2。如果返回-2,表示x坐标无变化。
代码:
typedef struct tagPOINT_2 {double x;double y;
}POINT_2, *PPOINT_2;int LineInfo(POINT_2 *pt_input, int ptNumbers, double * k, double * b)
{int nRet = 0;double X_aver = 0;double Y_aver = 0;double A = 0;double B = 0;double _2_XY_av = 0;double _2_XX_av = 0;do{if (ptNumbers < 2){nRet = -1;break;}for (int loop = 0; loop < ptNumbers; loop++){X_aver += pt_input[loop].x;Y_aver += pt_input[loop].y;_2_XY_av += pt_input[loop].x * pt_input[loop].y;_2_XX_av += pt_input[loop].x * pt_input[loop].x;}X_aver /= ptNumbers;Y_aver /= ptNumbers;_2_XY_av /= ptNumbers;_2_XX_av /= ptNumbers;for (int loop = 0; loop < ptNumbers; loop++){A += fabs((pt_input[loop].x - X_aver) * (pt_input[loop].y - Y_aver));B += fabs((pt_input[loop].x - X_aver) * (pt_input[loop].x - X_aver));}if (B < 0.000001){nRet = -2;break;}//方式一//*k = A / B;//*b = Y_aver - *k * X_aver;//方式二*k = (_2_XY_av - X_aver * Y_aver) / (_2_XX_av - X_aver * X_aver);*b = Y_aver - (*k) * X_aver;} while (0);return nRet;
}
测试代码:
#include <stdio.h>
#include <math.h>
int main()
{POINT_2 pt[10] = {{0.1 , 0.3},{1.2 , 2.0},{2.2 , 4.3},{3.1 , 5.8},{4.0 , 8.5},{5.3 , 10.8},{5.9 , 11.1},{6.8 , 13.9},{8.1 , 16.5},{9.0 , 17.9},};int ret;double k = 0, b = 0;ret = LineInfo(pt, 10, &k, &b);switch (ret){case 0: printf("拟合成功,直线为y = %lf * x + %lf\n", k, b); break;case -1: printf("拟合失败,传入的点少于二点\n"); break;case -2: printf("拟合失败,传入的点x坐标重合\n"); break;default:printf("error\n"); break;}return 0;
}
测试结果:

















