00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <math.h>
00043 #include <pcl/surface/poisson/factor.h>
00044
00045 namespace pcl {
00046 namespace poisson {
00047
00049
00051
00052 int Factor(double a1,double a0,double roots[1][2],const double& EPS){
00053 if(fabs(a1)<=EPS){return 0;}
00054 roots[0][0]=-a0/a1;
00055 roots[0][1]=0;
00056 return 1;
00057 }
00058 int Factor(double a2,double a1,double a0,double roots[2][2],const double& EPS){
00059 double d;
00060 if(fabs(a2)<=EPS){return Factor(a1,a0,roots,EPS);}
00061
00062 d=a1*a1-4*a0*a2;
00063 a1/=(2*a2);
00064 if(d<0){
00065 d=sqrt(-d)/(2*a2);
00066 roots[0][0]=roots[1][0]=-a1;
00067 roots[0][1]=-d;
00068 roots[1][1]= d;
00069 }
00070 else{
00071 d=sqrt(d)/(2*a2);
00072 roots[0][1]=roots[1][1]=0;
00073 roots[0][0]=-a1-d;
00074 roots[1][0]=-a1+d;
00075 }
00076 return 2;
00077 }
00078
00079
00080 int Factor(double a3,double a2,double a1,double a0,double roots[3][2],const double& EPS){
00081 double q,r,r2,q3;
00082
00083 if(fabs(a3)<=EPS){return Factor(a2,a1,a0,roots,EPS);}
00084 a2/=a3;
00085 a1/=a3;
00086 a0/=a3;
00087
00088 q=-(3*a1-a2*a2)/9;
00089 r=-(9*a2*a1-27*a0-2*a2*a2*a2)/54;
00090 r2=r*r;
00091 q3=q*q*q;
00092
00093 if(r2<q3){
00094 double sqrQ=sqrt(q);
00095 double theta = acos ( r / (sqrQ*q) );
00096 double cTheta=cos(theta/3)*sqrQ;
00097 double sTheta=sin(theta/3)*sqrQ*SQRT_3/2;
00098 roots[0][1]=roots[1][1]=roots[2][1]=0;
00099 roots[0][0]=-2*cTheta;
00100 roots[1][0]=-2*(-cTheta*0.5-sTheta);
00101 roots[2][0]=-2*(-cTheta*0.5+sTheta);
00102 }
00103 else{
00104 double s1,s2,sqr=sqrt(r2-q3);
00105 double t;
00106 t=-r+sqr;
00107 if(t<0){s1=-pow(-t,1.0/3);}
00108 else{s1=pow(t,1.0/3);}
00109 t=-r-sqr;
00110 if(t<0){s2=-pow(-t,1.0/3);}
00111 else{s2=pow(t,1.0/3);}
00112 roots[0][1]=0;
00113 roots[0][0]=s1+s2;
00114 s1/=2;
00115 s2/=2;
00116 roots[1][0]= roots[2][0]=-s1-s2;
00117 roots[1][1]= SQRT_3*(s1-s2);
00118 roots[2][1]=-roots[1][1];
00119 }
00120 roots[0][0]-=a2/3;
00121 roots[1][0]-=a2/3;
00122 roots[2][0]-=a2/3;
00123 return 3;
00124 }
00125 double ArcTan2(const double& y,const double& x){
00126
00127 if(y==0 && x==0){return 0;}
00128 if(x==0){
00129 if(y>0){return PI/2.0;}
00130 else{return -PI/2.0;}
00131 }
00132 if(x>=0){return atan(y/x);}
00133 else{
00134 if(y>=0){return atan(y/x)+PI;}
00135 else{return atan(y/x)-PI;}
00136 }
00137 }
00138 double Angle(const double in[2]){
00139 if((in[0]*in[0]+in[1]*in[1])==0.0){return 0;}
00140 else{return ArcTan2(in[1],in[0]);}
00141 }
00142 void Sqrt(const double in[2],double out[2]){
00143 double r=sqrt(sqrt(in[0]*in[0]+in[1]*in[1]));
00144 double a=Angle(in)*0.5;
00145 out[0]=r*cos(a);
00146 out[1]=r*sin(a);
00147 }
00148 void Add(const double in1[2],const double in2[2],double out[2]){
00149 out[0]=in1[0]+in2[0];
00150 out[1]=in1[1]+in2[1];
00151 }
00152 void Subtract(const double in1[2],const double in2[2],double out[2]){
00153 out[0]=in1[0]-in2[0];
00154 out[1]=in1[1]-in2[1];
00155 }
00156 void Multiply(const double in1[2],const double in2[2],double out[2]){
00157 out[0]=in1[0]*in2[0]-in1[1]*in2[1];
00158 out[1]=in1[0]*in2[1]+in1[1]*in2[0];
00159 }
00160 void Divide(const double in1[2],const double in2[2],double out[2]){
00161 double temp[2];
00162 double l=in2[0]*in2[0]+in2[1]*in2[1];
00163 temp[0]= in2[0]/l;
00164 temp[1]=-in2[1]/l;
00165 Multiply(in1,temp,out);
00166 }
00167
00168
00169 int Factor(double a4,double a3,double a2,double a1,double a0,double roots[4][2],const double& EPS){
00170 double R[2],D[2],E[2],R2[2];
00171
00172 if(fabs(a4)<EPS){return Factor(a3,a2,a1,a0,roots,EPS);}
00173 a3/=a4;
00174 a2/=a4;
00175 a1/=a4;
00176 a0/=a4;
00177
00178 Factor(1.0,-a2,a3*a1-4.0*a0,-a3*a3*a0+4.0*a2*a0-a1*a1,roots,EPS);
00179
00180 R2[0]=a3*a3/4.0-a2+roots[0][0];
00181 R2[1]=0;
00182 Sqrt(R2,R);
00183 if(fabs(R[0])>10e-8){
00184 double temp1[2],temp2[2];
00185 double p1[2],p2[2];
00186
00187 p1[0]=a3*a3*0.75-2.0*a2-R2[0];
00188 p1[1]=0;
00189
00190 temp2[0]=((4.0*a3*a2-8.0*a1-a3*a3*a3)/4.0);
00191 temp2[1]=0;
00192 Divide(temp2,R,p2);
00193
00194 Add (p1,p2,temp1);
00195 Subtract(p1,p2,temp2);
00196
00197 Sqrt(temp1,D);
00198 Sqrt(temp2,E);
00199 }
00200 else{
00201 R[0]=R[1]=0;
00202 double temp1[2],temp2[2];
00203 temp1[0]=roots[0][0]*roots[0][0]-4.0*a0;
00204 temp1[1]=0;
00205 Sqrt(temp1,temp2);
00206 temp1[0]=a3*a3*0.75-2.0*a2+2.0*temp2[0];
00207 temp1[1]= 2.0*temp2[1];
00208 Sqrt(temp1,D);
00209 temp1[0]=a3*a3*0.75-2.0*a2-2.0*temp2[0];
00210 temp1[1]= -2.0*temp2[1];
00211 Sqrt(temp1,E);
00212 }
00213
00214 roots[0][0]=-a3/4.0+R[0]/2.0+D[0]/2.0;
00215 roots[0][1]= R[1]/2.0+D[1]/2.0;
00216
00217 roots[1][0]=-a3/4.0+R[0]/2.0-D[0]/2.0;
00218 roots[1][1]= R[1]/2.0-D[1]/2.0;
00219
00220 roots[2][0]=-a3/4.0-R[0]/2.0+E[0]/2.0;
00221 roots[2][1]= -R[1]/2.0+E[1]/2.0;
00222
00223 roots[3][0]=-a3/4.0-R[0]/2.0-E[0]/2.0;
00224 roots[3][1]= -R[1]/2.0-E[1]/2.0;
00225 return 4;
00226 }
00227
00228 int Solve(const double* eqns,const double* values,double* solutions,const int& dim){
00229 int i,j,eIndex;
00230 double v,m;
00231 int *index=new int[dim];
00232 int *set=new int[dim];
00233 double* myEqns=new double[dim*dim];
00234 double* myValues=new double[dim];
00235
00236 for(i=0;i<dim*dim;i++){myEqns[i]=eqns[i];}
00237 for(i=0;i<dim;i++){
00238 myValues[i]=values[i];
00239 set[i]=0;
00240 }
00241 for(i=0;i<dim;i++){
00242
00243 m=-1;
00244 eIndex=-1;
00245 for(j=0;j<dim;j++){
00246 if(set[j]){continue;}
00247 if(myEqns[j*dim+i]!=0 && fabs(myEqns[j*dim+i])>m){
00248 m=fabs(myEqns[j*dim+i]);
00249 eIndex=j;
00250 }
00251 }
00252 if(eIndex==-1){
00253 delete[] index;
00254 delete[] myValues;
00255 delete[] myEqns;
00256 delete[] set;
00257 return 0;
00258 }
00259
00260 index[i]=eIndex;
00261 set[eIndex]=1;
00262
00263
00264 v=myEqns[eIndex*dim+i];
00265 for(j=0;j<dim;j++){myEqns[eIndex*dim+j]/=v;}
00266 myValues[eIndex]/=v;
00267
00268
00269 for(j=0;j<dim;j++){
00270 if(j==eIndex){continue;}
00271 double vv=myEqns[j*dim+i];
00272 for(int k=0;k<dim;k++){myEqns[j*dim+k]-=myEqns[eIndex*dim+k]*vv;}
00273 myValues[j]-=myValues[eIndex]*vv;
00274 }
00275 }
00276 for(i=0;i<dim;i++){solutions[i]=myValues[index[i]];}
00277 delete[] index;
00278 delete[] myValues;
00279 delete[] myEqns;
00280 delete[] set;
00281 return 1;
00282 }
00283
00284
00285 }
00286 }