00001 #include <V_3D.h>
00002
00003
00004
00005
00006 V_3D::V_3D()
00007 {
00008 for(int k_dim=0;k_dim<3;k_dim++)
00009 V[k_dim]=0;
00010 }
00011
00012 V_3D::~V_3D()
00013 {}
00014
00015 V_3D::V_3D(const V_3D &v_3d)
00016 {
00017 for(int k_dim=0;k_dim<3;k_dim++)
00018 V[k_dim] = v_3d.V[k_dim];
00019 }
00020
00021 V_3D::V_3D(double x,double y,double z)
00022 {
00023 V[0]=x;
00024 V[1]=y;
00025 V[2]=z;
00026 }
00027
00028 int V_3D::set(double *_v)
00029 {
00030 for(int k_dim=0;k_dim<3;k_dim++)
00031 V[k_dim]=_v[k_dim];
00032 return 0;
00033 }
00034 int V_3D::set(int k_dim,double value)
00035 {
00036 V[k_dim]=value;
00037 return 0;
00038 }
00039
00040 int V_3D::set(V_3D _V)
00041 {
00042 for(int k_dim=0;k_dim<3;k_dim++)
00043 V[k_dim]=_V.get(k_dim);
00044 return 0;
00045 }
00046
00047 int V_3D::set(double x,double y,double z)
00048 {
00049 V[0] = x;
00050 V[1] = y;
00051 V[2] = z;
00052 return 0;
00053 }
00054
00055 double V_3D::get(int k_dim) const
00056 {
00057 return V[k_dim];
00058 }
00059
00060 int V_3D::get(double *_v) const
00061 {
00062 for(int k_dim=0;k_dim<3;k_dim++)
00063 _v[k_dim]=V[k_dim];
00064 return 0;
00065 }
00066
00067 V_3D V_3D::get() const
00068 {
00069 return *this;
00070 }
00071
00072 double *V_3D::get_pointer()
00073 {
00074 return V;
00075 }
00076
00077 V_3D operator+(const V_3D& v1,const V_3D& v2)
00078 {
00079 V_3D Z;
00080 int k_dim=0;
00081 for(k_dim=0;k_dim<3;k_dim++)
00082 Z.set(k_dim,v1.V[k_dim]+v2.V[k_dim]);
00083 return Z;
00084 }
00085
00086 V_3D operator-(const V_3D& v1,const V_3D& v2)
00087 {
00088 V_3D Z;
00089 int k_dim=0;
00090 for(k_dim=0;k_dim<3;k_dim++)
00091 Z.set(k_dim,v1.V[k_dim]-v2.V[k_dim]);
00092 return Z;
00093 }
00094
00095 V_3D operator*(const double& alpha,const V_3D& v1)
00096 {
00097 V_3D Z;
00098 int k_dim=0;
00099 for(k_dim=0;k_dim<3;k_dim++)
00100 Z.set(k_dim,alpha*v1.V[k_dim]);
00101 return Z;
00102 }
00103
00104 V_3D operator*(const V_3D& v1,const double& alpha)
00105 {
00106 V_3D Z;
00107 int k_dim=0;
00108 for(k_dim=0;k_dim<3;k_dim++)
00109 Z.set(k_dim,alpha*v1.V[k_dim]);
00110 return Z;
00111 }
00112
00113
00114 V_3D operator/(const V_3D& v1,const double& alpha)
00115 {
00116 V_3D Z;
00117 int k_dim=0;
00118 for(k_dim=0;k_dim<3;k_dim++)
00119 Z.set(k_dim,v1.V[k_dim]/alpha);
00120 return Z;
00121 }
00122
00123
00124 double V_3D::dot(V_3D _v) const
00125 {
00126 double res=0.0;
00127 int k_dim=0;
00128 for(k_dim=0;k_dim<3;k_dim++)
00129 res += V[k_dim]*_v.get(k_dim);
00130 return res;
00131 }
00132
00133 double V_3D::norm() const
00134 {
00135 double res=0.0;
00136 int k_dim=0;
00137 for(k_dim=0;k_dim<3;k_dim++)
00138 res += V[k_dim]*V[k_dim];
00139
00140 return powf(res,0.5);
00141 }
00142
00143 V_3D& V_3D::operator=(const V_3D& _v)
00144 {
00145 for(int k_dim=0;k_dim<3;k_dim++)
00146 V[k_dim] = _v.V[k_dim];
00147 return *this;
00148 }
00149
00150 V_3D V_3D::vector_prod(V_3D _v) const
00151 {
00152 V_3D res;
00153
00154 res.set(0,V[1]*_v.get(2)-V[2]*_v.get(1));
00155 res.set(1,V[2]*_v.get(0)-V[0]*_v.get(2));
00156 res.set(2,V[0]*_v.get(1)-V[1]*_v.get(0));
00157
00158 return res;
00159 }
00160
00161 double V_3D::area(V_3D _v) const
00162 {
00163 return vector_prod(_v).norm()/2;
00164 }
00165
00166
00167 ostream& operator << (ostream& flux, V_3D _v)
00168 {
00169 flux<<"("<<_v.get(0)<<","<<_v.get(1)<<","<<_v.get(2)<<")";
00170 return flux;
00171 }
00172
00173 bool operator==(const V_3D& v1,const V_3D& v2)
00174 {
00175 double epsilon=0.0001;
00176 if(fabs(v1.V[0]-v2.V[0])<epsilon
00177 && fabs(v1.V[1]-v2.V[1])<epsilon
00178 && fabs(v1.V[2]-v2.V[2])<epsilon)
00179 return true;
00180 else
00181 return false;
00182 }
00183
00184 bool operator!=(const V_3D& v1,const V_3D& v2)
00185 {
00186 double epsilon=0.0001;
00187 if(fabs(v1.V[0]-v2.V[0])>=epsilon
00188 || fabs(v1.V[1]-v2.V[1])>=epsilon
00189 || fabs(v1.V[2]-v2.V[2])>=epsilon)
00190 return true;
00191 else
00192 return false;
00193 }
00194
00195
00196
00197 double& V_3D::operator[](int index)
00198 {
00199 if(index<0 || index>2)
00200 {printf("error in operator [] in V_3d, index [%d] not correct\n",index);exit(-1);}
00201 return V[index];
00202 }
00203 double V_3D::operator[](int index) const
00204 {
00205 if(index<0 || index>2)
00206 {printf("error in operator [] in V_3d, index [%d] not correct\n",index);exit(-1);}
00207 return V[index];
00208 }
00209
00210 V_3D& V_3D::operator+=(const V_3D& _v)
00211 {
00212 V[0] += _v[0];
00213 V[1] += _v[1];
00214 V[2] += _v[2];
00215 return *this;
00216 }
00217 V_3D& V_3D::operator/=(const double& alpha)
00218 {
00219 for(int k_dim=0;k_dim<3;k_dim++)
00220 V[k_dim] /= alpha;
00221 return *this;
00222 }
00223
00224 V_3D V_3D::get_min_scalar(const V_3D& _v) const
00225 {
00226 V_3D temp;
00227 for(int k_dim=0;k_dim<3;k_dim++)
00228 temp[k_dim]=(V[k_dim]<_v[k_dim]?V[k_dim]:_v[k_dim]);
00229 return temp;
00230 }
00231 V_3D V_3D::get_max_scalar(const V_3D& _v) const
00232 {
00233 V_3D temp;
00234 for(int k_dim=0;k_dim<3;k_dim++)
00235 temp[k_dim]=(V[k_dim]>_v[k_dim]?V[k_dim]:_v[k_dim]);
00236 return temp;
00237 }
00238
00239 double V_3D::get_max_of_coeff() const
00240 {return max(max(V[0],V[1]),V[2]);}
00241 double V_3D::get_min_of_coeff() const
00242 {return min(min(V[0],V[1]),V[2]);}
00243
00244
00245 int V_3D::equal(const V_3D& v,double epsilon) const
00246 {
00247 if(powf((V[0]-v[0])*(V[0]-v[0])+(V[1]-v[1])*(V[1]-v[1])+(V[2]-v[2])*(V[2]-v[2]),0.5)<=epsilon)
00248 return 1;
00249 else
00250 return 0;
00251 }
00252
00253 bool V_3D::operator>=(const V_3D &v) const
00254 {
00255 if(V[0]>=v[0] && V[1]>=v[1] && V[2]>=v[2])
00256 return 1;
00257 return 0;
00258 }
00259 bool V_3D::operator>(const V_3D &v) const
00260 {
00261 if(V[0]>v[0] && V[1]>v[1] && V[2]>v[2])
00262 return 1;
00263 return 0;
00264 }
00265 bool V_3D::operator<=(const V_3D &v) const
00266 {
00267 if(V[0]<=v[0] && V[1]<=v[1] && V[2]<=v[2])
00268 return 1;
00269 return 0;
00270 }
00271 bool V_3D::operator<(const V_3D &v) const
00272 {
00273 if(V[0]<v[0] && V[1]<v[1] && V[2]<v[2])
00274 return 1;
00275 return 0;
00276 }
00277
00278 double V_3D::tetrahedra_volume(const V_3D& p2,const V_3D& p3,const V_3D& p4) const
00279 {
00280
00281
00282
00283 V_3D AB=p2-*this;
00284 V_3D AC=p3-*this;
00285 V_3D AD=p4-*this;
00286
00287 double Vol=0.0;
00288 Vol = 0.5 * (AB.vector_prod(AC)).dot(AD);
00289 return Vol;
00290 }
00291
00292 int V_3D::get_barycenter_coordinates_tetrahedra(const V_3D& p1,const V_3D& p2,const V_3D& p3,const V_3D& p4,double *alpha,double *beta,double *gamma,double *delta) const
00293 {
00294 double Va=(*this).tetrahedra_volume(p2,p3,p4);
00295 double Vb=p1.tetrahedra_volume(*this,p3,p4);
00296 double Vc=p1.tetrahedra_volume(p2,*this,p4);
00297 double Vd=p1.tetrahedra_volume(p2,p3,*this);
00298 double Vtot=p1.tetrahedra_volume(p2,p3,p4);
00299
00300 *alpha=Va/Vtot;
00301 *beta =Vb/Vtot;
00302 *gamma=Vc/Vtot;
00303 *delta=Vd/Vtot;
00304
00305 return 0;
00306 }
00307
00308 int V_3D::is_inside_volume(const V_3D& p1,const V_3D& p2,const V_3D& p3,const V_3D& p4) const
00309 {
00310 double alpha=0.0,beta=0.0,gamma=0.0,delta=0.0;
00311 get_barycenter_coordinates_tetrahedra(p1,p2,p3,p4,&alpha,&beta,&gamma,&delta);
00312
00313 if(alpha>0 && beta>0 && gamma>0 && delta>0)
00314 return 1;
00315 return 0;
00316 }
00317
00318 double V_3D::distance_to_oriented_plane(const V_3D& n,const V_3D& x0) const
00319 {
00320
00321 double epsilon=0.000001;
00322 double norm_n=n.norm();
00323 if(norm_n<epsilon)
00324 {printf("Error n is null in distance to oriented_plane in V_3D...\n");exit(-1);}
00325 V_3D n_normalized=n/norm_n;
00326
00327 double proj = ((*this)-x0).dot(n_normalized);
00328 return proj;
00329 }
00330
00331 double V_3D::cos_angle(const V_3D& v) const
00332 {
00333 V_3D current = (*this)/(*this).norm();
00334 V_3D vn = v/v.norm();
00335
00336 return current.dot(vn);
00337 }
00338
00339 double V_3D::angle(const V_3D& v)const
00340 {return acos(cos_angle(v));}
00341
00342 double V_3D::cos_angle_to_plane_with_normal(const V_3D& normal_to_plane) const
00343 {
00344 double norm_normal=normal_to_plane.norm();
00345 if(norm_normal<=0.000001)
00346 {printf("Error in angle_to_plane_with_normal in V_3D, normal has norm=0\n");exit(-1);}
00347 double current_norm=norm();
00348 V_3D this_normed = (*this)/current_norm;
00349 V_3D projected = this_normed - (this_normed.dot(normal_to_plane))*normal_to_plane;
00350 double projected_norm= this_normed.norm();
00351 if(projected_norm<0.00001)
00352 {printf("Error in angle_to_plane_with_normal in V_3D, projected_normal has norm=0\n");exit(-1);}
00353 projected = projected/projected_norm;
00354 double dot_prod=this_normed.dot(projected);
00355
00356 return dot_prod;
00357 }
00358
00359 V_3D V_3D::normalized() const
00360 {
00361 double epsilon=0.00001;
00362 double current_norm=norm();
00363 if(current_norm<epsilon)
00364 {
00365
00366 return V_3D(0,0,1);
00367 }
00368 return (*this)/current_norm;
00369 }