00001
00002 #include <MC_segment.hpp>
00003
00004 #include <MC_v3d_vector.hpp>
00005 #include <MC_double_vector.hpp>
00006 #include <MC_int_pair.hpp>
00007
00008 namespace mesh_conv
00009 {
00010
00011 MC_segment::MC_segment(){}
00012 MC_segment::MC_segment(const MC_v3d& start_point,const MC_v3d& end_point)
00013 {x0=start_point;x1=end_point;}
00014 MC_segment::MC_segment(const MC_segment& s){x0=s.x0;x1=s.x1;}
00015
00016 MC_segment::~MC_segment(){}
00017
00018
00019 MC_v3d MC_segment::unit_vector() const {return vector().normalized();}
00020 MC_v3d MC_segment::vector() const {return x1-x0;}
00021 MC_segment MC_segment::fliped() const {return MC_segment(x1,x0);}
00022
00023
00024 double MC_segment::length() const {return vector().norm();}
00025 MC_v3d MC_segment::closest_point(const MC_v3d& x) const
00026 {
00027 MC_v3d u=unit_vector();
00028 double proj=0.0;
00029 proj = (x-x0).dot(u);
00030 if(proj<0)
00031 return x0;
00032 else if(proj>length())
00033 return x1;
00034 else
00035 return x0+proj*u;
00036 }
00037
00038 double MC_segment::distance_to_point(const MC_v3d& x) const {return (x-closest_point(x)).norm();}
00039 MC_segment MC_segment::closest_to_segment(const MC_segment& s) const
00040 {
00041
00042
00043
00044
00045
00046
00047
00048 MC_v3d u1,u2;
00049 MC_v3d A12;
00050
00051 u1 = vector();
00052 u2 = s.vector();
00053 A12 = s[0]-x0;
00054
00055 double det=0.0;
00056 det = powf(float(u1.dot(u2)),2.0) - u1.dot(u1)*u2.dot(u2);
00057
00058
00059 double epsilon=0.00001;
00060 if(fabs(det)<epsilon)
00061 {std::cout<<"Error in MC_segment::closest_to_segment(), lines are almost parallel"<<std::endl;exit(-1);}
00062
00063
00064 double s1=0.0,s2=0.0;
00065 s1 = 1/det*(-(A12.dot(u1))*(u2.dot(u2)) + (A12.dot(u2))*(u1.dot(u2)) );
00066 s2 = 1/det*(-(A12.dot(u1))*(u2.dot(u1)) + (A12.dot(u2))*(u1.dot(u1)) );
00067
00068 MC_v3d A1=x0,A2=s[0];
00069 MC_v3d P1;P1 = A1 + s1*u1;
00070 MC_v3d P2;P2 = A2 + s2*u2;
00071
00072
00073 double dot_p1=0.0,dot_p2=0.0;
00074 dot_p1 = (P1-A1).dot(u1);
00075 dot_p2 = (P2-A2).dot(u2);
00076
00077 MC_segment seg;
00078 int is_valid_p1=0,is_valid_p2=0;
00079 if(dot_p1>=0 && dot_p1<=u1.dot(u1))
00080 is_valid_p1=1;
00081 if(dot_p2>=0 && dot_p2<=u2.dot(u2))
00082 is_valid_p2=1;
00083
00084 if(is_valid_p1==1 && is_valid_p2==1)
00085 seg=MC_segment(P1,P2);
00086 else
00087 {
00088
00089
00090 MC_v3d y0[3]={A1,A1+u1,P1};
00091 MC_v3d y1[3]={A2,A2+u2,P2};
00092 double min_dist=99999.99;
00093 double current_dist=0.0;
00094 int min_k1=-1,min_k2=-1;
00095 for(int k1=0;k1<3;k1++)
00096 for(int k2=0;k2<3;k2++)
00097 {
00098 current_dist=(y0[k1]-y1[k2]).norm();
00099 if(current_dist<min_dist)
00100 if(k1!=2 || (k1==2 && is_valid_p1==1))
00101 if(k2!=2 || (k2==2 && is_valid_p2==1))
00102 {min_dist=current_dist;min_k1=k1;min_k2=k2;}
00103 }
00104
00105
00106 if(min_k1==0 && min_k2==0) {seg=MC_segment(A1,A2);}
00107 else if(min_k1==0 && min_k2==1) {seg=MC_segment(A1,A2+u2);}
00108 else if(min_k1==0 && min_k2==2) {seg=MC_segment(A1,P2);}
00109
00110 else if(min_k1==1 && min_k2==0) {seg=MC_segment(A1+u1,A2);}
00111 else if(min_k1==1 && min_k2==1) {seg=MC_segment(A1+u1,A2+u2);}
00112 else if(min_k1==1 && min_k2==2) {seg=MC_segment(A1+u1,P2);}
00113
00114 else if(min_k1==2 && min_k2==0) {seg=MC_segment(P1,A2);}
00115 else if(min_k1==2 && min_k2==1) {seg=MC_segment(P1,A2+u2);}
00116 else if(min_k1==2 && min_k2==2) {seg=MC_segment(P1,P2);}
00117
00118 }
00119
00120 return seg;
00121
00122 }
00123
00124
00125 double MC_segment::distance_to_segment(const MC_segment& s) const
00126 {return closest_to_segment(s).length();}
00127
00128 MC_v3d MC_segment::plane_intersection(const MC_v3d& n,const MC_v3d& _x0,int *type) const
00129 {
00130 double epsilon=0.00001;
00131
00132 MC_v3d AB=x1-x0;
00133 if(fabs(AB.dot(n))<epsilon)
00134 {
00135
00136
00137 if(fabs(n.dot(_x0-x0))<epsilon)
00138 {
00139 if(type!=0)
00140 *type=3;
00141 return MC_v3d(-1,-1,-1);
00142 }
00143 else
00144 {
00145 if(type!=0)
00146 *type=0;
00147 return MC_v3d(-1,-1,-1);
00148 }
00149 }
00150
00151
00152 double t=n.dot(_x0-x0)/AB.dot(n);
00153
00154 MC_v3d intersection=x0+t*AB;
00155
00156
00157
00158
00159 if(t>=0 && t<=1)
00160 {
00161
00162 if( ((intersection-x0).norm()<epsilon) || ((intersection-x1).norm()<epsilon) )
00163 {if(type!=0) *type=2;}
00164 else
00165 {if(type!=0) *type=1;}
00166 return intersection;
00167 }
00168
00169
00170 if(type!=0) *type=0;
00171 return intersection;
00172 }
00173
00174 bool MC_segment::is_belonging(const MC_v3d& x,int *type) const
00175 {
00176 bool belongs=0;
00177 double t = relative_position(x,&belongs);
00178 if(belongs!=1)
00179 {
00180 if(type!=0) *type=-2;
00181 return false;
00182 }
00183 else if(t<0 || t>1)
00184 {
00185 if(type!=0) *type=-1;
00186 return false;
00187 }
00188 if(type!=0) *type=1;
00189 return true;
00190 }
00191 bool MC_segment::is_aligned(const MC_v3d& x) const
00192 {
00193 double epsilon=0.0001;
00194 return ((x-x0)-(x-x0).dot(unit_vector())*unit_vector()).norm()<epsilon;
00195 }
00196 double MC_segment::relative_position(const MC_v3d& x,bool *_is_aligned) const
00197 {
00198
00199 if(is_aligned(x)==false)
00200 {
00201 if(_is_aligned!=0)
00202 *_is_aligned=false;
00203 return 0.0;}
00204
00205 if(_is_aligned!=0)
00206 *_is_aligned=true;
00207 return (x-x0).dot(unit_vector())/length();
00208 }
00209 void MC_segment::assert_bounds(const int& u) const
00210 {
00211 if(u!=0 && u!=1)
00212 {std::cout<<"Error in MC_segment::assert_bounds("<<u<<"), value should be 0 or 1"<<std::endl;exit(-1);}
00213 }
00214 MC_v3d MC_segment::operator()(const int& index) const
00215 {assert_bounds(index); if(index==0)return x0;if(index==1) return x1;exit(-1);}
00216 MC_v3d& MC_segment::operator()(const int& index)
00217 {assert_bounds(index); if(index==0)return x0;if(index==1) return x1;exit(-1);}
00218 MC_v3d MC_segment::operator[](const int& index) const
00219 {assert_bounds(index); if(index==0)return x0;if(index==1) return x1;exit(-1);}
00220 MC_v3d& MC_segment::operator[](const int& index)
00221 {assert_bounds(index); if(index==0)return x0;if(index==1) return x1;exit(-1);}
00222
00223 MC_v3d MC_segment::value(const double& t) const
00224 {return (1-t)*x0+t*x1;}
00225 MC_v3d_vector MC_segment::value(const MC_double_vector& t) const
00226 {return (1-t)*x0+t*x1;}
00227
00228
00229
00230 std::pair<MC_v3d_vector,MC_double_vector> MC_segment::linear_sampling_intervals(const double& d_L) const
00231 {
00232 double epsilon=0.00001;
00233 if(d_L<=epsilon)
00234 {std::cout<<"Error in MC_segment::linear_sampling_intervals("<<d_L<<"), interval is too low"<<std::endl;exit(-1);}
00235
00236 double total_length=length();
00237 int N_subdiv=int(total_length/d_L+1);
00238
00239 return linear_sampling(N_subdiv);
00240 }
00241 std::pair<MC_v3d_vector,MC_double_vector> MC_segment::linear_sampling(const int& N) const
00242 {
00243 MC_double_vector t_value=MC_double_vector::zeros(N);
00244 MC_v3d_vector sampling=MC_v3d_vector::zeros(N);
00245 for(int k=0;k<N;k++)
00246 {
00247 double u=double(k)/double(N-1);
00248 sampling(k) = (1-u)*x0 + u*x1;
00249 t_value(k)=u;
00250 }
00251 return std::pair<MC_v3d_vector,MC_double_vector> (sampling,t_value);
00252 }
00253 MC_segment operator+(const MC_segment& s,const MC_v3d& x)
00254 {return MC_segment(s[0]+x,s[1]+x);}
00255 MC_segment operator+(const MC_v3d& x,const MC_segment& s)
00256 {return s+x;}
00257 MC_segment operator*(const MC_segment& s,const double& a)
00258 {return MC_segment(s[0]*a,s[1]*a);}
00259 MC_segment operator*(const double& a,const MC_segment& s)
00260 {return s*a;}
00261
00262 std::ostream& operator << (std::ostream& stream, const MC_segment& s)
00263 {stream<<"["<<s[0]<<" ; "<<s[1]<<"]";return stream;}
00264
00265 std::vector<MC_segment> MC_segment::build_segment_vector(const MC_v3d_vector& vertices,const std::vector<MC_int_pair>& constraints)
00266 {
00267 unsigned int N_vertices=vertices.size();
00268 std::vector<MC_segment> v_seg;
00269 for(int k=0,N=constraints.size();k<N;++k)
00270 {
00271 const MC_int_pair& index=constraints[k];
00272 if(index[0]>=N_vertices || index[1]>=N_vertices)
00273 {std::cout<<"Error in MC_segment::build_segment_vector(), index "<<index<<" is too large compared to N_vertex="<<N_vertices<<" at k="<<k<<std::endl;exit(-1);}
00274 v_seg.push_back(MC_segment(vertices[index[0]],vertices[index[1]]));
00275 }
00276 return v_seg;
00277 }
00278
00279
00280 }