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 }