MC_v3d.cpp

Go to the documentation of this file.
00001 
00002 #include <MC_string_helper.hpp>
00003 #include <MC_v3d.hpp>
00004 #include <cmath>
00005 
00006 #include <MC_v3d_vector.hpp>
00007 #include <MC_matrix.hpp>
00008 #include <MC_quaternion.hpp>
00009 #include <MC_segment.hpp>
00010 
00011 
00012 namespace mesh_conv
00013 {
00014 
00015 MC_v3d::MC_v3d()
00016 {v[0]=0;v[1]=0;v[2]=0;}
00017 
00018 MC_v3d::MC_v3d(const double& x,const double& y,const double& z)
00019 {v[0]=x;v[1]=y;v[2]=z;}
00020 
00021 MC_v3d::~MC_v3d(){}
00022 
00023 MC_v3d::MC_v3d(const MC_v3d_vector& vec)
00024 {
00025     if(vec.size()==1)
00026         *this=vec.first();
00027     else
00028     {std::cout<<"Error in MC_v3d::MC_v3d(const MC_v3d_vector& "<<vec<<"), size must be 1"<<std::endl;exit(-1);}
00029 }
00030 
00031 const double& MC_v3d::operator()(const int& k_dim) const
00032 {
00033     if(k_dim<0 || k_dim>2)
00034     {std::cout<<"Error in const MC_v3d("<<k_dim<<"), size must be 0,1 or 2"<<std::endl;exit(-1);}
00035     return v[k_dim];
00036 }
00037 double& MC_v3d::operator()(const int& k_dim)
00038 {
00039     if(k_dim<0 || k_dim>2)
00040     {std::cout<<"Error in MC_v3d("<<k_dim<<"), size must be 0,1 or 2"<<std::endl;exit(-1);}
00041     return v[k_dim];
00042 }
00043 const double& MC_v3d::operator[](const int& k_dim) const
00044 {
00045     if(k_dim<0 || k_dim>2)
00046     {std::cout<<"Error in const MC_v3d["<<k_dim<<"], size must be 0,1 or 2"<<std::endl;exit(-1);}
00047     return v[k_dim];
00048 }
00049 double& MC_v3d::operator[](const int& k_dim)
00050 {
00051     if(k_dim<0 || k_dim>2)
00052     {std::cout<<"Error in MC_v3d["<<k_dim<<"], size must be 0,1 or 2"<<std::endl;exit(-1);}
00053     return v[k_dim];
00054 }
00055 MC_v3d::MC_v3d(const MC_v3d& _v)
00056 {v[0]=_v[0];v[1]=_v[1];v[2]=_v[2];}
00057 
00058 MC_v3d::MC_v3d(const double* _v)
00059 {v[0]=_v[0];v[1]=_v[1];v[2]=_v[2];}
00060 
00061 MC_v3d MC_v3d::operator-() const
00062 {return MC_v3d(-v[0],-v[1],-v[2]);}
00063 
00064 
00065 MC_v3d operator+(const MC_v3d& vec,const double& to_add)
00066 {return MC_v3d(vec[0]+to_add,vec[1]+to_add,vec[2]+to_add);}
00067 MC_v3d operator-(const MC_v3d& vec,const double& to_sub)
00068 {return MC_v3d(vec[0]-to_sub,vec[1]-to_sub,vec[2]-to_sub);}
00069 MC_v3d operator*(const MC_v3d& vec,const double& to_mult)
00070 {return MC_v3d(vec[0]*to_mult,vec[1]*to_mult,vec[2]*to_mult);}
00071 MC_v3d operator*(const double& to_mult,const MC_v3d& vec)
00072 {return vec*to_mult;}
00073 
00074 MC_v3d operator/(const MC_v3d& vec,const double& to_subdiv)
00075 {
00076     double epsilon=0.000000001;
00077     if(fabs(to_subdiv)<epsilon)
00078     {std::cout<<"Error in MC_v3d("<<vec<<"/"<<to_subdiv<<", divide by zero"<<std::endl;exit(-1);}
00079 
00080     return MC_v3d(vec[0]/to_subdiv,vec[1]/to_subdiv,vec[2]/to_subdiv);
00081 }
00082 MC_v3d operator+(const MC_v3d& vec,const MC_v3d& to_add)
00083 {return MC_v3d(vec[0]+to_add[0],vec[1]+to_add[1],vec[2]+to_add[2]);}
00084 MC_v3d operator-(const MC_v3d& vec,const MC_v3d& to_sub)
00085 {return MC_v3d(vec[0]-to_sub[0],vec[1]-to_sub[1],vec[2]-to_sub[2]);}
00086 
00087 MC_v3d& MC_v3d::operator+=(const double& to_add)
00088 {
00089     v[0]+=to_add;v[1]+=to_add;v[2]+=to_add;
00090     return *this;
00091 }
00092 
00093 MC_v3d& MC_v3d::operator-=(const double& to_sub)
00094 {
00095     v[0]-=to_sub;v[1]-=to_sub;v[2]-=to_sub;
00096     return *this;
00097 }
00098 MC_v3d& MC_v3d::operator*=(const double& to_mult)
00099 {
00100     v[0]*=to_mult;v[1]*=to_mult;v[2]*=to_mult;
00101     return *this;
00102 }
00103 MC_v3d& MC_v3d::operator/=(const double& to_subdiv)
00104 {
00105     double epsilon=0.000000001;
00106     if(fabs(to_subdiv)<epsilon)
00107     {std::cout<<"Error in MC_v3d("<<*this<<"/="<<to_subdiv<<", divide by zero"<<std::endl;exit(-1);}
00108 
00109     v[0]/=to_subdiv;v[1]/=to_subdiv;v[2]/=to_subdiv;
00110     return *this;
00111 }
00112 MC_v3d& MC_v3d::operator+=(const MC_v3d& to_add){
00113     v[0]+=to_add[0];v[1]+=to_add[1];v[2]+=to_add[2];
00114     return *this;
00115 }
00116 MC_v3d& MC_v3d::operator-=(const MC_v3d& to_sub){
00117     v[0]-=to_sub[0];v[1]-=to_sub[1];v[2]-=to_sub[2];return *this;
00118 }
00119 
00120 
00121 std::ostream& operator<<(std::ostream& stream,const MC_v3d& v)
00122 {
00123     stream<<"("<<v[0]<<","<<v[1]<<","<<v[2]<<")";
00124     return stream;
00125 }
00126 
00127 MC_v3d::MC_v3d(const std::string& s)
00128 {
00129     std::vector <std::string> v_s=mesh_conv::MC_string_tokenizer::tokenize(s," (),;");
00130 
00131     int number_ok=0;
00132     for(unsigned int k=0;number_ok<3 && k<v_s.size();k++)
00133     {
00134         bool is_converted=false;
00135         double temp_value=MC_string_converter::value_of<double>(v_s[k],&is_converted);
00136         if(is_converted==true)
00137             v[number_ok++]=temp_value;
00138     }
00139 
00140 }
00141 
00142 
00143     bool operator>>(std::istream& stream,MC_v3d& vec)
00144     {
00145         int current_position=0;
00146         std::string temp_string;
00147         while(current_position<3 && stream.good())
00148         {
00149             if(stream>>temp_string)
00150             {
00151                 std::vector <std::string> v_token=MC_string_tokenizer::tokenize(temp_string,",;() ");
00152 
00153                 for(unsigned int k=0;current_position<3 && k<v_token.size();++k)
00154                 {
00155                     bool is_converted=false;
00156                     double temp_value=MC_string_converter::value_of<double>(v_token[k],&is_converted);
00157                     if(is_converted==true)
00158                         vec[current_position++]=temp_value;
00159                 }
00160             }
00161         }
00162         return 0;
00163     }
00164 
00165     MC_v3d& MC_v3d::scale(const double& sx,const double& sy,const double& sz)
00166     {v[0]*=sx;v[1]*=sy;v[2]*=sz;return *this;}
00167     MC_v3d MC_v3d::mask(const double& sx,const double& sy,const double& sz) const
00168     {return MC_v3d(v[0]*sx,v[1]*sy,v[2]*sz);}
00169     MC_v3d& MC_v3d::scale(const MC_v3d& scaling){v[0]*=scaling[0];v[1]*=scaling[1];v[2]*=scaling[2];return *this;}
00170     MC_v3d MC_v3d::mask(const MC_v3d& scaling) const{return MC_v3d(v[0]*scaling[0],v[1]*scaling[1],v[2]*scaling[2]);}
00171     MC_v3d& MC_v3d::scale(const double& scaling){return (*this)*=scaling;}
00172     MC_v3d MC_v3d::scale(const double& scaling) const{return (*this)*scaling;}
00173 
00174     MC_v3d MC_v3d::scaled(const MC_v3d& scaling) const
00175     {return MC_v3d(v[0]*scaling[0],v[1]*scaling[1],v[2]*scaling[2]);}
00176     MC_v3d MC_v3d::scaled(const double& scaling) const
00177     {return MC_v3d(v[0]*scaling,v[1]*scaling,v[2]*scaling);}
00178 
00179 
00180     double MC_v3d::dot(const MC_v3d& vec) const
00181     {return v[0]*vec[0]+v[1]*vec[1]+v[2]*vec[2];}
00182     MC_v3d MC_v3d::cross(const MC_v3d& vec) const
00183     {return MC_v3d(v[1]*vec[2]-v[2]*vec[1],v[2]*vec[0]-v[0]*vec[2],v[0]*vec[1]-v[1]*vec[0]);}
00184     double MC_v3d::norm() const
00185     {return sqrt(dot(*this));}
00186     MC_v3d MC_v3d::normalized() const
00187     {
00188         double epsilon=0.000000001;
00189         double n=norm();
00190         if(n<epsilon)
00191         {//std::cout<<"Warning in MC_v3d::normalized(), norm is "<<n<<std::endl;
00192             return MC_v3d(0,0,1);}
00193         return (*this)/n;
00194     }
00195 
00196     std::pair <MC_v3d,MC_v3d_vector> MC_v3d::normalized_with_gradient() const
00197     {
00198         MC_v3d_vector nabla=MC_v3d_vector::zeros(3);
00199 
00200         double norm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
00201         double epsilon=0.00000001;
00202         if(norm<epsilon)
00203             return std::pair <MC_v3d,MC_v3d_vector> (MC_v3d(0,0,1),nabla);
00204 
00205         MC_v3d n_normalized=MC_v3d(v[0]/norm,v[1]/norm,v[2]/norm);
00206         nabla[0]=1/norm*(MC_v3d(1,0,0)-n_normalized*v[0]/norm);
00207         nabla[1]=1/norm*(MC_v3d(0,1,0)-n_normalized*v[1]/norm);
00208         nabla[2]=1/norm*(MC_v3d(0,0,1)-n_normalized*v[2]/norm);
00209 
00210         return std::pair<MC_v3d,MC_v3d_vector> (n_normalized,nabla);
00211     }
00212 
00213 
00214 
00215     MC_v3d& MC_v3d::operator*=(const MC_matrix& M)
00216     {M.internal_product(this); return *this;}
00217 
00218     MC_v3d::MC_v3d(const MC_matrix& M)
00219     {
00220         if( ( (M.size_1()==3 || M.size_1()==4) && M.size_2()==1) ||
00221             ( (M.size_2()==3 || M.size_2()==4) && M.size_1()==1) )
00222         {v[0]=M(0);v[1]=M(1);v[2]=M(2);}
00223     }
00224 
00225     MC_v3d& MC_v3d::operator=(const MC_matrix& M)
00226     {*this=MC_v3d(M);return *this;}
00227 
00228     MC_v3d operator*(const MC_quaternion& q,const MC_v3d& vec)
00229     {
00230         MC_quaternion q_b=q.conjugated();
00231         MC_quaternion v_quat;
00232         v_quat.set_v3d(vec);
00233 
00234         MC_quaternion result = q*v_quat*q_b;
00235         return MC_v3d(result[0],result[1],result[2]);
00236     }
00237     MC_v3d& MC_v3d::operator*=(const MC_quaternion& q)
00238     {
00239         MC_quaternion q_b=q.conjugated();
00240         MC_quaternion v_quat(*this,0);
00241         v_quat = q*v_quat*q_b;
00242         v[0]=v_quat[0];v[1]=v_quat[1];v[2]=v_quat[2];
00243         return *this;
00244     }
00245     const double* MC_v3d::pointer() const{return v;}
00246 
00247     bool operator==(const MC_v3d& a1,const MC_v3d& a2)
00248     {
00249         MC_v3d_less L;
00250         if(L(a1,a2)==false && L(a2,a1)==false)
00251             return true;
00252         return false;
00253     }
00254     bool operator!=(const MC_v3d& a1,const MC_v3d& a2)
00255     {return !(a1==a2);}
00256 
00257     double MC_v3d::area(const MC_v3d& v0,const MC_v3d& v1)
00258     {
00259         return (v0.cross(v1)).norm()/2.0;
00260     }
00261 
00262     double MC_v3d::cotan(const MC_v3d& u0,const MC_v3d& u1)
00263     {
00264        double div=(u0.cross(u1)).norm();
00265 
00266        double epsilon=0.00000001;
00267        if(div<epsilon)
00268        {std::cout<<"Error in V_3D::cotan(), points are aligned"<<std::endl;return 0.0;}
00269 
00270        return (u0.dot(u1))/(div);
00271     }
00272     double* MC_v3d::pointer_unprotected() {return &v[0];}
00273 
00274     double MC_v3d::angle(const MC_v3d& u0,const MC_v3d& u1)
00275     {
00276         double epsilon=0.00001;
00277         double n0=u0.norm(),n1=u1.norm();
00278         if(n0>epsilon && n1>epsilon)
00279         {
00280             double dot=u0.dot(u1)/(n0*n1);
00281             if(dot>=1.0)
00282                 return 0.0;
00283             if(dot<=-1.0)
00284                 return M_PI;
00285             return acos(dot);
00286         }
00287         else
00288             return 0.0;
00289     }
00290 
00291     MC_v3d MC_v3d::project_on_plane(const MC_v3d& normal) const
00292     {
00293         double epsilon=0.00001;
00294         if(normal.norm()<epsilon)
00295             return *this;
00296         MC_v3d n=normal.normalized();
00297         return (*this)-(*this).dot(n)*n;
00298     }
00299 
00300     MC_v3d::MC_v3d(const MC_double_vector& vec)
00301     {
00302         if(vec.size()!=3)
00303         {std::cout<<"Error in MC_v3d::MC_v3d(MC_double_vector), size ="<<vec.size()<<"!=3"<<std::endl;exit(-1);}
00304 
00305         for(int k_dim=0;k_dim<3;++k_dim)
00306             v[k_dim]=vec[k_dim];
00307     }
00308 
00309     std::string MC_v3d::to_string() const
00310     {
00311         std::stringstream stream;
00312         stream<<*this;
00313         return stream.str();
00314     }
00315 
00316     MC_v3d MC_v3d::project_on_line(const MC_v3d& dir) const
00317     {
00318         MC_v3d u=dir.normalized();
00319         return (*this).dot(u)*u;
00320     }
00321     MC_v3d MC_v3d::project_on_line(const MC_segment& seg) const
00322     {
00323         MC_v3d u=seg.unit_vector();
00324         return seg[0]+((*this)-seg[0]).dot(u)*u;
00325     }
00326     void MC_v3d::set_zero()
00327     {v[0]=0;v[1]=0;v[2]=0;}
00328 }

Generated on Sun Apr 18 20:24:47 2010 by  doxygen 1.6.1