#include<stdio.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>
#include <gsl/gsl_sf_bessel.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_blas.h>
#include"plane.h"
/*计算点到平面的距离,有正负;
double cch_point_to_plane_distance(Cch_point *point,Cch_point * plane_point, Cch_point * plane_vector)
{
cch_unit_vector_m2(plane_vector);
double vector[3];
vector[0] = point->x - plane_point->x;
vector[1] = point->y - plane_point->y;
vector[2] = point->z - plane_point->z;
double distance;
distance = vector[0]*plane_vector->x + vector[1]*plane_vector->y + vector[2]*plane_vector->z;
return distance;
}*/
gsl_matrix *
matrix_mul
(gsl_matrix * a, gsl_matrix * b
) //计算矩阵的乘积a*b
{
int i,j,k;
double aa,bb,m =
0;
gsl_matrix * c = gsl_matrix_alloc
(a->size1,b->size2
);
if (a->size2 != b->size1
)
{
printf ("matrix multiply matrix Error!\n");
return NULL;
}
for(i=
0; i < a->size1; i++
)
{
for(j=
0; j < b->size2; j++
)
{
for(k=
0; k < a->size2; k++
)
{
aa = gsl_matrix_get
(a, i, k
);
bb = gsl_matrix_get
(b, k, j
);
m+=aa*bb;
}
gsl_matrix_set
(c,i,j,m
);
m =
0;
}
}
return c;
}
gsl_matrix *
matrix_T
(gsl_matrix * a
) //计算矩阵的转置
{
int i,j;
gsl_matrix * aT = gsl_matrix_alloc
(a->size2, a->size1
);
for(i =
0; i < aT->size1; i++
)
for(j =
0; j < aT->size2; j++
)
gsl_matrix_set
(aT,i,j,gsl_matrix_get
(a,j,i
));
return aT;
}
gsl_matrix *
m2_matrix_n
(gsl_matrix * U, gsl_vector * S, gsl_matrix * V
) //利用SVD分解求矩阵A的逆
{
int i,j;
gsl_matrix * s = gsl_matrix_alloc
(U->size2,U->size2
);
gsl_matrix * u = gsl_matrix_alloc
(U->size2,U->size1
);
gsl_matrix * f = gsl_matrix_alloc
(V->size1,s->size2
);
gsl_matrix * An = gsl_matrix_alloc
(f->size1,u->size2
);
gsl_matrix_set_zero
(s
);
for(i =
0; i < s->size1; i++
)
gsl_matrix_set
(s,i,i,
1/
(gsl_vector_get
(S,i
)));
u = matrix_T
(U
);
//f = matrix_mul(V,s); //利用自己编写的函数计算矩阵的乘积
gsl_blas_dgemm
(CblasNoTrans, CblasNoTrans,
1.0, V, s,
0.0, f
);
//利用GSL函数直接求矩阵的乘积
//An = matrix_mul(f,u);
gsl_blas_dgemm
(CblasNoTrans, CblasNoTrans,
1.0, f, u,
0.0, An
);
return An;
}
/********************************
* 函数名称:cch_least_plane
* 函数功能:least_plane
* 输入参数:待拟合的点
* 输出参数:无
* 返 回 值:拟合直线
* 日 期:2008-8-18
* *******************************/
Cch_plane cch_least_plane
(double **point,
int num
)
{
gsl_matrix * A = gsl_matrix_alloc
(num,
4);
int i;
for(i=
0;i<num;i++
)
{
gsl_matrix_set
(A, i,
0, point
[i
][0]);
gsl_matrix_set
(A, i,
1, point
[i
][1]);
gsl_matrix_set
(A, i,
2, point
[i
][2]);
gsl_matrix_set
(A, i,
3,
1);
}
gsl_matrix * AT;
AT=matrix_T
(A
);
gsl_matrix *ATA;
ATA=matrix_mul
(AT,A
);
gsl_matrix * V = gsl_matrix_alloc
(A->size2,A->size2
);
gsl_vector * S = gsl_vector_alloc
(A->size2
);
gsl_linalg_SV_decomp_jacobi
(ATA,V,S
);
int S_min_id=
0;
double S_min=gsl_vector_get
(S,
0);
for(i=
1;i<
4;i++
)
{
if(gsl_vector_get
(S,i
)<S_min
)
{
S_min=gsl_vector_get
(S,S_min_id
);
S_min_id=i;
}
}
Cch_plane plane;
plane.
vector.
x=gsl_matrix_get
(V,
0,S_min_id
);
plane.
vector.
y=gsl_matrix_get
(V,
1,S_min_id
);
plane.
vector.
z=gsl_matrix_get
(V,
2,S_min_id
);
double plane_d;
plane_d=gsl_matrix_get
(V,
3,S_min_id
);
double plane_vector_max;
if(fabs
(plane.
vector.
x) > fabs
(plane.
vector.
y))
plane_vector_max=plane.
vector.
x;
else
plane_vector_max=plane.
vector.
y;
if(fabs
(plane.
vector.
z) > fabs
(plane_vector_max
))
plane_vector_max=plane.
vector.
z;
if(plane_vector_max == plane.
vector.
z)
{
plane.
center.
x=
0;
plane.
center.
y=
0;
plane.
center.
z=-plane_d/plane.
vector.
z;
}
else if(plane_vector_max == plane.
vector.
x)
{
plane.
center.
x=-plane_d/plane.
vector.
x;
plane.
center.
y=
0;
plane.
center.
z=
0;
}
else if(plane_vector_max == plane.
vector.
y)
{
plane.
center.
x=
0;
plane.
center.
y=-plane_d/plane.
vector.
y;
plane.
center.
z=
0;
}
else
printf("plane vector has error!\n");
double plane_vector_m;
plane_vector_m = plane.
vector.
x*plane.
vector.
x
+ plane.
vector.
y*plane.
vector.
y
+ plane.
vector.
z*plane.
vector.
z;
plane_vector_m=sqrt
(plane_vector_m
);
plane.
vector.
x=plane.
vector.
x/plane_vector_m;
plane.
vector.
y=plane.
vector.
y/plane_vector_m;
plane.
vector.
z=plane.
vector.
z/plane_vector_m;
gsl_matrix_free
(A
);
gsl_matrix_free
(AT
);
gsl_matrix_free
(ATA
);
gsl_matrix_free
(V
);
gsl_vector_free
(S
);
return plane;
}