00001
00002 #include <MC_segment.hpp>
00003 #include <MC_double_vector.hpp>
00004
00005
00006 #include <MC_triangle.hpp>
00007
00008
00009 namespace mesh_conv
00010 {
00011
00012 MC_v3d MC_triangle::normal() const
00013 {
00014
00015 MC_v3d v0=v[1]-v[0];
00016 MC_v3d v1=v[2]-v[0];
00017
00018 MC_v3d n=v0.cross(v1);
00019 double nn=n.norm();
00020 double epsilon=0.00000001;
00021 if(nn<epsilon)
00022 {std::cout<<"Warning in MC_triangle::normal(), from triangle "<<*this<<", normal is "<<n<<" of norm()="<<nn<<std::endl;return MC_v3d(0,0,1);}
00023 n/=nn;
00024 return n;
00025 }
00026
00027 MC_v3d MC_triangle::barycenter() const
00028 {return 1.0/3.0*(v[0]+v[1]+v[2]);}
00029
00030 MC_triangle::MC_triangle(){resize(3);}
00031 MC_triangle::MC_triangle(const MC_v3d& v0,const MC_v3d& v1,const MC_v3d& v2)
00032 :MC_v3d_vector(v0,v1,v2)
00033 {}
00034 MC_triangle::MC_triangle(const MC_v3d_vector& vec)
00035 :MC_v3d_vector()
00036 {
00037 if(vec.size()!=3)
00038 {std::cout<<"Error in MC_triangle::MC_triangle("<<vec<<"), size should be 3"<<std::endl;exit(-1);}
00039 resize(3);
00040 v[0]=vec[0];v[1]=vec[1];v[2]=vec[2];
00041 }
00042 MC_triangle::MC_triangle(const std::vector <MC_v3d>& vec)
00043 :MC_v3d_vector()
00044 {
00045 if(vec.size()!=3)
00046 {std::cout<<"Error in MC_triangle::MC_triangle(std::vector <MC_v3d>), size should be 3 and not "<<vec.size()<<std::endl;exit(-1);}
00047 resize(3);
00048 v[0]=vec[0];v[1]=vec[1];v[2]=vec[2];
00049 }
00050 MC_triangle::MC_triangle(const MC_triangle& p)
00051 :MC_v3d_vector(p)
00052 {v=p.v;}
00053
00054 MC_v3d MC_triangle::closest_point(const MC_v3d& x,int *type) const
00055 {
00056
00057 double epsilon=0.00001;
00058
00059
00060 MC_v3d n=normal();
00061 MC_v3d proj = x-((x-v[0]).dot(n))*n;
00062
00063
00064 if(is_inside(proj)==1)
00065 {
00066 if(type!=0)
00067 *type=0;
00068 return proj;
00069 }
00070
00071
00072
00073 if(type!=0)
00074 *type=1;
00075 MC_segment s0=segment(0),s1=segment(1),s2=segment(2);
00076 MC_v3d y0=s0.closest_point(x),y1=s1.closest_point(x),y2=s2.closest_point(x);
00077 double dist_1=(y0-x).norm(),dist_2=(y1-x).norm(),dist_3=(y2-x).norm();
00078 if(dist_1<=dist_2 && dist_1<=dist_3)
00079 {
00080
00081 for(int k=0;k<3;k++){if((y0-v[k]).norm()<epsilon) *type=2;}
00082 return y0;
00083 }
00084 else if(dist_2<=dist_1 && dist_2<=dist_3)
00085 {
00086 for(int k=0;k<3;k++){if((y1-v[k]).norm()<epsilon) *type=2;}
00087 return y1;
00088 }
00089 else
00090 {
00091 for(int k=0;k<3;k++){if((y2-v[k]).norm()<epsilon) *type=2;}
00092 return y2;
00093 }
00094
00095 }
00096
00097 bool MC_triangle::is_inside(const MC_v3d& _x) const
00098 {
00099 std::pair <MC_double_vector,bool> bar=barycentric_coordinates(_x);
00100 if(bar.second==false)
00101 return false;
00102 double epsilon=0.0001;
00103 if(bar.first[0]>1.0 || bar.first[1]>1.0 || bar.first[2]>1.0 || (bar.first[0]+bar.first[1]+bar.first[2]-1.0)>epsilon)
00104 return false;
00105
00106
00107 return true;
00108 }
00109
00110 std::pair<MC_double_vector,bool> MC_triangle::barycentric_coordinates(const MC_v3d& x) const
00111 {
00112
00113 double epsilon=0.0001;
00114 double L = (x-v[0]).dot(normal());
00115 if(L>epsilon)
00116 return std::pair <MC_double_vector,bool> (MC_double_vector(-1,-1,-1),false);
00117
00118
00119 double area_1=MC_v3d::area(v[1]-v[0],x-v[0]);
00120 double area_2=MC_v3d::area(v[2]-v[1],x-v[1]);
00121 double area_3=MC_v3d::area(v[0]-v[2],x-v[2]);
00122 double area_tot = area();
00123
00124 MC_double_vector b(area_1/area_tot,area_2/area_tot,area_3/area_tot);
00125 return std::pair <MC_double_vector,bool> (b,true);
00126 }
00127
00128 MC_segment MC_triangle::segment(const int& edge_number) const
00129 {
00130 if(edge_number<0 || edge_number>2)
00131 {std::cout<<"MC_triangle::segment("<<edge_number<<"),_k_edge has to be between 0 and 2"<<std::endl;exit(-1);}
00132
00133 return MC_segment(v[edge_number],v[(edge_number+1)%3]);
00134 }
00135
00136 double MC_triangle::area() const
00137 {
00138 return MC_v3d::area(v[1]-v[0],v[2]-v[0]);
00139 }
00140
00141 MC_triangle::MC_triangle(const MC_polygon& p)
00142 {
00143 if(p.size()!=3)
00144 {std::cout<<"Error in MC_triangle::MC_triangle("<<p<<"), size must be 3 and not "<<p.size()<<std::endl;exit(-1);}
00145 resize(3);
00146 v[0]=p[0];v[1]=p[1];v[2]=p[2];
00147 }
00148 std::vector<MC_triangle> MC_triangle::triangulate(const MC_polygon& p)
00149 {
00150 int N=p.size();
00151 std::vector <MC_triangle> vtri(N-2);
00152 for(int k_triangle=0;k_triangle<N-2;k_triangle++)
00153 vtri[k_triangle]=MC_triangle(p[0],p[k_triangle+1],p[k_triangle+2]);
00154 return vtri;
00155 }
00156
00157 MC_v3d MC_triangle::segment_intersection(const MC_segment& s,int *type) const
00158 {
00159 int temp_type=0;
00160 MC_v3d i=s.plane_intersection(normal(),v[0],&temp_type);
00161
00162 if(type!=0)
00163 *type=temp_type;
00164
00165 if(temp_type==0 || temp_type==3)
00166 return i;
00167
00168 if(is_inside(i)==false)
00169 if(type!=0)
00170 *type=0;
00171
00172 return i;
00173 }
00174
00175 MC_v3d MC_triangle::pn_triangle(const MC_v3d_vector& X,const MC_v3d_vector& N,const MC_double_vector& x)
00176 {
00177 MC_double_vector w=MC_double_vector::zeros(9);
00178 for(int i=0;i<3;++i)
00179 for(int j=0;j<3;++j)
00180 w[3*i+j]=(X[j]-X[i]).dot(N[i]);
00181
00182 MC_v3d b300=X[0];
00183 MC_v3d b030=X[1];
00184 MC_v3d b003=X[2];
00185
00186 MC_v3d b210=(2*X[0]+X[1]-w[0*3+1]*N[0])/3.0;
00187 MC_v3d b120=(2*X[1]+X[0]-w[1*3+0]*N[1])/3.0;
00188 MC_v3d b021=(2*X[1]+X[2]-w[1*3+2]*N[1])/3.0;
00189 MC_v3d b012=(2*X[2]+X[1]-w[2*3+1]*N[2])/3.0;
00190 MC_v3d b102=(2*X[2]+X[0]-w[2*3+0]*N[2])/3.0;
00191 MC_v3d b201=(2*X[0]+X[2]-w[0*3+2]*N[0])/3.0;
00192 MC_v3d E=(b210+b120+b021+b012+b102+b201)/6.0;
00193 MC_v3d V=(X[0]+X[1]+X[2])/3.0;
00194 MC_v3d b111=E+(E-V)/2.0;
00195
00196 MC_v3d y=b300*x[0]*x[0]*x[0]+b030*x[1]*x[1]*x[1]+b003*x[2]*x[2]*x[2]+
00197 b210*3.0*x[0]*x[0]*x[1]+b120*3.0*x[0]*x[1]*x[1]+b201*3.0*x[0]*x[0]*x[2]+
00198 b021*3.0*x[1]*x[1]*x[2]+b102*3.0*x[0]*x[2]*x[2]+b012*3.0*x[1]*x[2]*x[2]+
00199 b111*6.0*x[0]*x[1]*x[2];
00200
00201 return y;
00202 }
00203
00204 MC_matrix MC_triangle::inertia() const
00205 {
00206 MC_v3d x0=(*this)[0];
00207 MC_v3d x1=(*this)[1];
00208 MC_v3d x2=(*this)[2];
00209
00210 double a=((x1-x0).cross(x2-x0)).norm();
00211
00212 MC_matrix S(3,3);
00213 S(0,0)=2;S(0,1)=1;S(0,2)=1;
00214 S(1,0)=1;S(1,1)=2;S(1,2)=1;
00215 S(2,0)=1;S(2,1)=1;S(2,2)=2;
00216 S*=1.0/24.0;
00217
00218 MC_matrix V(x0,x1,x2);
00219
00220 MC_matrix C=a*V*S*V.transposed();
00221 MC_matrix J=C.trace()*MC_matrix(3)-C;
00222
00223 return J;
00224 }
00225
00226 }