factor.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2009-2012, Willow Garage, Inc.
00006  *  Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho,
00007  *                      Johns Hopkins University
00008  *
00009  *  All rights reserved.
00010  *
00011  *  Redistribution and use in source and binary forms, with or without
00012  *  modification, are permitted provided that the following conditions
00013  *  are met:
00014  *
00015  *   * Redistributions of source code must retain the above copyright
00016  *     notice, this list of conditions and the following disclaimer.
00017  *   * Redistributions in binary form must reproduce the above
00018  *     copyright notice, this list of conditions and the following
00019  *     disclaimer in the documentation and/or other materials provided
00020  *     with the distribution.
00021  *   * Neither the name of Willow Garage, Inc. nor the names of its
00022  *     contributors may be used to endorse or promote products derived
00023  *     from this software without specific prior written permission.
00024  *
00025  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00026  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00027  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00028  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00029  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00030  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00031  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00032  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00033  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00034  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00035  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  *  POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * $Id: factor.cpp 5027 2012-03-12 03:10:45Z rusu $
00039  *
00040  */
00041 
00042 #include <math.h>
00043 #include <pcl/surface/poisson/factor.h>
00044 
00045 namespace pcl {
00046   namespace poisson {
00047 
00049     // Polynomial Roots //
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     // Solution taken from: http://mathworld.wolfram.com/CubicFormula.html
00079     // and http://www.csit.fsu.edu/~burkardt/f_src/subpak/subpak.f90
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       /* This first case should never happen */
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     // Solution taken from: http://mathworld.wolfram.com/QuarticEquation.html
00168     // and http://www.csit.fsu.edu/~burkardt/f_src/subpak/subpak.f90
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         // Find the largest equation that has a non-zero entry in the i-th index
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         // The position in which the solution for the i-th variable can be found
00260         index[i]=eIndex;
00261         set[eIndex]=1;
00262 
00263         // Normalize the equation
00264         v=myEqns[eIndex*dim+i];
00265         for(j=0;j<dim;j++){myEqns[eIndex*dim+j]/=v;}
00266         myValues[eIndex]/=v;
00267 
00268         // Subtract it off from everything else
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 }


pcl
Author(s): Open Perception
autogenerated on Mon Oct 6 2014 03:15:02