Container class for a polygon. More...
#include <MC_polygon.hpp>


Public Member Functions | |
| MC_polygon () | |
| empty constructor | |
| MC_polygon (const MC_v3d &v0, const MC_v3d &v1, const MC_v3d &v2) | |
| constructor from a triangle | |
| MC_polygon (const MC_v3d &v0, const MC_v3d &v1, const MC_v3d &v2, const MC_v3d &v3) | |
| constructor from a quad | |
| MC_polygon (const MC_v3d &v0, const MC_v3d &v1, const MC_v3d &v2, const MC_v3d &v3, const MC_v3d &v4) | |
| constructor from a pentagone | |
| MC_polygon (const MC_v3d_vector &vec) | |
| copy constructor | |
| MC_polygon (const std::vector< MC_v3d > &vec) | |
| direct constructor from a vector of MC_v3d | |
| MC_polygon (const MC_polygon &p) | |
| copy constructor | |
| bool | is_planar () const |
| check if the polygon is planar. | |
| MC_v3d | normal () const |
| get the normal of the polygon (assume it is almost planar). | |
| MC_v3d | barycenter () const |
| get the barycenter of the polygon | |
| bool | is_inside (const MC_v3d &_x) const |
| check if a vertex (in plane) is inside the polygon | |
| bool | is_outside (const MC_v3d &_x) const |
| check if a vertex (in plane) is outside the polygon | |
| MC_v3d | closest_point (const MC_v3d &x, int *type=0) const |
| get shortest position on the polygon between the polygon and the point | |
| MC_double_vector | barycentric_coordinates (const MC_v3d &x) const |
| get the generalized barycentric coordinates | |
| MC_int_vector | position (const MC_v3d &x) const |
| return the type of position of a vertex with respect to the polygon | |
| MC_v3d_vector | plane_intersection (const MC_v3d &n, const MC_v3d &x0, int *type=0, MC_int_vector *type_edge=0) const |
| Intersection with the plane of equation <n,x-x0>=0. | |
| MC_polygon | half_space_intersection (const MC_v3d &n, const MC_v3d &x0, int *type=0) const |
| get the intersection of the polygon and the half space defined by the oriented plane <n,x-x0>=0 | |
| MC_v3d | segment_intersection (const MC_segment &s, int *type=0) const |
| segment_intersection | |
| std::pair< MC_v3d, std::pair < int, std::pair< int, double > > > | projected_direction (const MC_v3d &x0, const MC_v3d &d, const MC_int_vector &forbidden_edge=MC_int_vector(-1)) const |
| project a point in the given direction (coplanar to the polygon) | |
| bool | is_degenerated () const |
| check if the polygon is degenerated (same vertices) | |
| std::pair< MC_polygon, std::pair< bool, bool > > | undegenerated () const |
| return a polygon not degenerated if possible | |
| std::pair< MC_polygon, MC_matrix > | rotate_to_plane (const MC_v3d &normal) const |
| rotate the polygon into a plane defined by its normal (if polygon is planar) | |
| std::pair< std::vector < MC_polygon >, std::pair < MC_mesh_index_vector, std::pair< MC_int_vector, MC_int_vector > > > | subdivide_mid_edge (const MC_int_vector &constraint_edges=MC_int_vector()) const |
| split the given polygon by linking consecutiv mid edges but with constraint on the given edge to not add extra mid edge | |
| std::pair< std::vector < MC_polygon >, std::pair < MC_mesh_index_vector, std::pair< MC_int_vector, MC_int_vector > > > | subdivide_barycenter_mid_edge (const MC_int_vector &constraint_edges=MC_int_vector()) const |
| split the given polygon by linking barycenter to the consecutiv mid edges but with constraint on the given edge to not add extra mid edge | |
| std::pair< std::vector < MC_polygon >, std::pair < MC_mesh_index_vector, std::pair< MC_int_vector, MC_int_vector > > > | subdivide_mixed_mid_edge (const MC_int_vector &constraint_edges=MC_int_vector()) const |
| subdivision of vertices adapted to polygon type | |
| MC_segment | segment (const int &edge_number) const |
| get the segment of the given edge | |
Private Member Functions | |
| std::vector< MC_polygon > | subdivide_mid_edge_no_constraint () const |
| split the given polygon by linking consecutiv edges | |
| std::vector< MC_polygon > | subdivide_barycenter_mid_edge_no_constraint () const |
| split the given polygon by linking barycenter to the middle edges | |
Container class for a polygon.
Internal structure is a vector of MC_v3d
Definition at line 38 of file MC_polygon.hpp.
| mesh_conv::MC_polygon::MC_polygon | ( | ) |
empty constructor
Definition at line 58 of file MC_polygon.cpp.
Referenced by subdivide_mid_edge(), subdivide_mid_edge_no_constraint(), and undegenerated().
00059 :MC_v3d_vector() 00060 {}

constructor from a triangle
Definition at line 61 of file MC_polygon.cpp.
00062 :MC_v3d_vector(v0,v1,v2) 00063 {}
| mesh_conv::MC_polygon::MC_polygon | ( | const MC_v3d & | v0, | |
| const MC_v3d & | v1, | |||
| const MC_v3d & | v2, | |||
| const MC_v3d & | v3 | |||
| ) |
constructor from a quad
Definition at line 64 of file MC_polygon.cpp.
00065 :MC_v3d_vector(v0,v1,v2,v3) 00066 {}
| mesh_conv::MC_polygon::MC_polygon | ( | const MC_v3d & | v0, | |
| const MC_v3d & | v1, | |||
| const MC_v3d & | v2, | |||
| const MC_v3d & | v3, | |||
| const MC_v3d & | v4 | |||
| ) |
constructor from a pentagone
Definition at line 67 of file MC_polygon.cpp.
00068 :MC_v3d_vector(v0,v1,v2,v3,v4) 00069 {}
| mesh_conv::MC_polygon::MC_polygon | ( | const MC_v3d_vector & | vec | ) |
| mesh_conv::MC_polygon::MC_polygon | ( | const std::vector< MC_v3d > & | vec | ) |
direct constructor from a vector of MC_v3d
Definition at line 74 of file MC_polygon.cpp.
00075 :MC_v3d_vector(vec) 00076 {}
| mesh_conv::MC_polygon::MC_polygon | ( | const MC_polygon & | p | ) |
copy constructor
Definition at line 77 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::v.
00078 :MC_v3d_vector(p) 00079 {v=p.v;}
| MC_v3d mesh_conv::MC_polygon::barycenter | ( | ) | const |
get the barycenter of the polygon
Reimplemented from mesh_conv::MC_v3d_vector.
Definition at line 55 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::size(), mesh_conv::MC_v3d_vector::sum(), and mesh_conv::MC_v3d_vector::v.
Referenced by mesh_conv::MC_opengl_drawer::draw_normal_per_polygon(), subdivide_barycenter_mid_edge(), and subdivide_barycenter_mid_edge_no_constraint().
00056 {return MC_v3d_vector::sum(v)/size();}


| MC_double_vector mesh_conv::MC_polygon::barycentric_coordinates | ( | const MC_v3d & | x | ) | const |
get the generalized barycentric coordinates
see [Meyer, Lee, Barr, Desbrun: Generalized Barycentric Coordinates on Irregular Polygons]
Definition at line 434 of file MC_polygon.cpp.
References mesh_conv::MC_v3d::cotan(), position(), mesh_conv::MC_segment::relative_position(), segment(), mesh_conv::MC_v3d_vector::size(), mesh_conv::MC_v3d_vector::sum(), mesh_conv::MC_v3d_vector::v, and mesh_conv::MC_v3d_vector::zeros().
Referenced by mesh_conv::MC_mesh_index_vector::barycentric_coordinates().
00435 { 00436 int N=size(); 00437 MC_double_vector bar=MC_double_vector::zeros(N); 00438 00439 //check the position 00440 MC_int_vector pos=position(p); 00441 00442 if(pos[0]==3) 00443 {std::cout<<"Warning in Polygon::barycentric_coordinates("<<p<<") is not in polygon"<<std::endl;return bar;} 00444 if(pos[0]==2) // vertex 00445 {bar[pos[1]]=1.0;return bar;} 00446 if(pos[0]==1) // edge 00447 { 00448 double alpha=segment(pos[1]).relative_position(p); 00449 bar[pos[1]] = 1-alpha; 00450 bar[(pos[1]+1)%N] = alpha; 00451 00452 return bar; 00453 } 00454 00455 //else inside the polygon 00456 for(int k=0;k<N;k++) 00457 { 00458 int kp=k-1<0?N-1:k-1; 00459 int kn=(k+1)%N; 00460 00461 double dist2=(p-v[k]).dot(p-v[k]); 00462 bar[k]=(MC_v3d::cotan(p-v[k],v[kp]-v[k])+MC_v3d::cotan(p-v[k],v[kn]-v[k]))/dist2; 00463 } 00464 00465 bar/=MC_double_vector::sum(bar); 00466 return bar; 00467 }


get shortest position on the polygon between the polygon and the point
type the type of point as pointer (default=null)
type = 0: interior point in the polygon
type = 1: edge point
type = 2: vertex point
A vertex is inside the polygon (in the plane) if it lies on one of its triangulation
Definition at line 81 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::closest(), mesh_conv::MC_segment::closest_point(), mesh_conv::MC_segment::distance_to_point(), is_inside(), normal(), mesh_conv::MC_v3d_vector::size(), mesh_conv::MC_triangle::triangulate(), and mesh_conv::MC_v3d_vector::v.
00082 { 00083 00084 00085 if(size()<=2) 00086 {std::cout<<"MC_polygon::closest_point(), polygon size is not ok ["<<size()<<"]"<<std::endl;exit(-1);} 00087 00088 double epsilon=0.0001; 00089 MC_v3d n = normal(); 00090 00091 // get the projection on the plane 00092 MC_v3d projection=x-((x-v[0]).dot(n))*n; 00093 00094 // get triangulation 00095 std::vector <MC_triangle> triangles=MC_triangle::triangulate(*this); 00096 00097 // first, try to find if the projection is inside the polygon (in one of the triangle) 00098 for(unsigned int k=0;k<triangles.size();k++) 00099 { 00100 if(triangles[k].is_inside(projection)==1) 00101 { 00102 if(type!=0) 00103 *type=0; 00104 return projection; 00105 } 00106 } 00107 00108 // then, the projection is outside the polygon 00109 // find the closest edge 00110 MC_v3d x0,x1,closest;MC_segment s;double L=0.0,L_min=9999.9; 00111 int closest_edge=-1; 00112 for(int k=0;k<size();k++) 00113 { 00114 00115 x0 = v[k]; 00116 x1 = v[(k+1)%size()]; 00117 s=MC_segment(x0,x1); 00118 00119 L = s.distance_to_point(projection); 00120 if(L<L_min) 00121 { 00122 closest = s.closest_point(projection); 00123 closest_edge = k; 00124 L_min=L; 00125 } 00126 } 00127 00128 if(type!=0) 00129 *type = 1; 00130 //look if the closest point is inside an edge, or a vertex 00131 for(int k=0;k<size();k++) 00132 if( (closest-v[k]).norm() < epsilon) //then it is close to a vertex 00133 if(type!=0) 00134 *type=2; 00135 return closest; 00136 }

| MC_polygon mesh_conv::MC_polygon::half_space_intersection | ( | const MC_v3d & | n, | |
| const MC_v3d & | x0, | |||
| int * | type = 0 | |||
| ) | const |
get the intersection of the polygon and the half space defined by the oriented plane <n,x-x0>=0
| n | the normal of the intersecting-plane | |
| x0 | a point on the plane | |
| type | for the type of intersection (default 0) |
3 Possibilies for type:
0 - unchanged polygon
1 - partly cutted polygon
2 - no more polygon at all
Definition at line 240 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::add(), normal(), plane_intersection(), and mesh_conv::MC_v3d_vector::size().
Referenced by mesh_conv::MC_mesh_index_vector::half_space_intersection().
00241 { 00242 //first take the intersection of the polygon and the plane 00243 MC_v3d_vector intersection; 00244 int type_edges=0; 00245 intersection = plane_intersection(n,x0,&type_edges); 00246 00247 00248 00249 //check if we need to cut or not the polygon 00250 MC_polygon new_polygon; 00251 if(type_edges!=1) // no change or just destroy the polygon 00252 { 00253 if(((*this)[0]-x0).dot(n)<0)//check the orientation of the polygon to the plane 00254 { 00255 //negative so there is no more polygons 00256 if(type!=0) 00257 *type=2; 00258 new_polygon.add(MC_v3d(-1.0,-1.0,-1.0)); 00259 return new_polygon; 00260 } 00261 else 00262 { 00263 // the polygon is unchanged 00264 if(type!=0) 00265 *type=0; 00266 return *this; 00267 } 00268 } 00269 00270 //else there is a modification to bring to the polygon 00271 00272 if(type!=0) 00273 *type=1; 00274 MC_segment s(intersection[0],intersection[1]); 00275 MC_v3d old_normal=normal(); 00276 00277 //first add every points in the correct half space 00278 //(just to be sure that we know the vertex before the line) 00279 00280 //find the first vertex in half space 00281 int k=0; 00282 while(((*this)[k]-x0).dot(n)<0) 00283 k++; 00284 int k_2=k; 00285 00286 int added_line=0; 00287 do 00288 { 00289 if( ((*this)[k_2]-x0).dot(n)>0 ) 00290 new_polygon.add((*this)[k_2]); 00291 else if(added_line==0) 00292 { 00293 // check if the line is in the right sense (we are sure that (*this[k2-1] already exists)) 00294 if( ((s[1]-s[0]).cross(s[0]-(*this)[(k_2-1)<0?size()-1:k_2-1])).dot(old_normal)<0) 00295 {new_polygon.add(s[0]);new_polygon.add(s[1]);} 00296 else{new_polygon.add(s[1]);new_polygon.add(s[0]);} 00297 added_line=1; 00298 } 00299 k_2=(k_2+1)%size(); 00300 }while(k_2!=k); 00301 00302 return new_polygon; 00303 }


| bool mesh_conv::MC_polygon::is_degenerated | ( | ) | const |
check if the polygon is degenerated (same vertices)
Definition at line 745 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
Referenced by mesh_conv::MC_mesh_index_vector::added_polygon_soup().
00746 { 00747 std::set <MC_v3d,MC_v3d_less> set_poly; 00748 int N=size(); 00749 for(int k=0;k<N;k++) 00750 if(set_poly.insert(v[k]).second==false) 00751 return true; 00752 return false; 00753 }


| bool mesh_conv::MC_polygon::is_inside | ( | const MC_v3d & | _x | ) | const |
check if a vertex (in plane) is inside the polygon
Definition at line 327 of file MC_polygon.cpp.
References mesh_conv::MC_triangle::triangulate().
Referenced by closest_point(), is_outside(), and segment_intersection().
00328 { 00329 std::vector <MC_triangle> t = MC_triangle::triangulate(*this); 00330 int N=t.size(); 00331 for(int k=0;k<N;k++) 00332 if(t[k].is_inside(x)==true) 00333 return true; 00334 return false; 00335 }


| bool mesh_conv::MC_polygon::is_outside | ( | const MC_v3d & | _x | ) | const |
check if a vertex (in plane) is outside the polygon
Definition at line 336 of file MC_polygon.cpp.
References is_inside().
Referenced by position().
00337 {return !is_inside(_x);}


| bool mesh_conv::MC_polygon::is_planar | ( | ) | const |
check if the polygon is planar.
Definition at line 14 of file MC_polygon.cpp.
References normal(), mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
00015 { 00016 00017 int N=size(); 00018 if(N<3) 00019 {std::cout<<"Error in MC_polygon::is_planar(), size is "<<N<<"<3"<<std::endl;exit(-1);} 00020 MC_v3d n=normal(); 00021 00022 double tol=0.0001; 00023 for(int k=1;k<N;k++) 00024 if( fabs((v[k]-v[0]).dot(n))>tol ) 00025 return false; 00026 return true; 00027 }

| MC_v3d mesh_conv::MC_polygon::normal | ( | ) | const |
get the normal of the polygon (assume it is almost planar).
Definition at line 29 of file MC_polygon.cpp.
References mesh_conv::MC_v3d::cross(), mesh_conv::MC_v3d::norm(), mesh_conv::MC_v3d_vector::normalized(), mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
Referenced by closest_point(), mesh_conv::MC_opengl_drawer::draw(), mesh_conv::MC_opengl_drawer::draw_per_polygon_color(), half_space_intersection(), mesh_conv::MC_mesh_index_vector::intersection_curve(), is_planar(), mesh_conv::MC_mesh_index_vector::normal_vertex(), and projected_direction().
00030 { 00031 int N=size(); 00032 if(N<3) 00033 {std::cout<<"Error in MC_polygon::normal(), size is "<<N<<"<3"<<std::endl;exit(-1);} 00034 00035 MC_v3d n; 00036 for(int k=0;k<N-2;k++) 00037 { 00038 MC_v3d v0,v1; 00039 v0=(v[k+1]-v[k]).normalized(); 00040 v1=(v[k+2]-v[k]).normalized(); 00041 n+=v0.cross(v1); 00042 } 00043 00044 double nn=n.norm(); 00045 00046 double epsilon=0.000000001; 00047 if(nn<epsilon) 00048 { 00049 //std::cout<<"Warning in MC_polygon::normal(), from polygon "<<*this<<", normal is "<<n<<" of norm()="<<nn<<std::endl; 00050 return MC_v3d(0,0,1);} 00051 n/=nn; 00052 return n; 00053 }


| MC_v3d_vector mesh_conv::MC_polygon::plane_intersection | ( | const MC_v3d & | n, | |
| const MC_v3d & | x0, | |||
| int * | type = 0, |
|||
| MC_int_vector * | type_edge = 0 | |||
| ) | const |
Intersection with the plane of equation <n,x-x0>=0.
| n,: | the normal | |
| x0,: | a point of the plane | |
| type,: | the type of intersection (defaut null) | |
| type_edge,: | the detailed interesection type by edge (defaut null) |
The plane is defined by its normal n, and a point x0, so its equation is <n,x-x0>=0
4 possibilities:
_ no intersections (type 0) => return void vector
_ plane intersect on two distinct points (type 1) => return vector of size 2
_ plane intersect only on a vertex (type 2) => return vector of size 1
_ plane intersect along an edge of the Polygon (type 3 > return the two extreme vertices) => return a vector of size 2
(temp_type_edge[k_1]==2 && temp_type_edge[k_2]==2)
Definition at line 138 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::add(), mesh_conv::MC_v3d_vector::last(), mesh_conv::MC_int_vector::resize(), segment(), mesh_conv::MC_v3d_vector::size(), mesh_conv::MC_v3d_vector::v, and mesh_conv::MC_v3d_vector::zeros().
Referenced by half_space_intersection().
00139 { 00140 std::cout<<"enter plane intersection"<<std::endl; 00141 00142 MC_v3d_vector intersections; 00143 00144 // First, take every intersection with every segment 00145 00146 std::vector <MC_segment> s; 00147 MC_v3d_vector inter; 00148 if(type_edge!=0) 00149 type_edge->resize(size()); 00150 MC_int_vector temp_type_edge=MC_int_vector::zeros(size()); 00151 00152 for(int k=0;k<size();k++) 00153 { 00154 s.push_back(segment(k)); 00155 inter.add(s[k].plane_intersection(n,x0,&temp_type_edge[k])); 00156 00157 std::cout<<temp_type_edge[k]<<" :"<<inter.last()<<std::endl; 00158 if(type_edge!=0) 00159 (*type_edge)[k]=temp_type_edge[k]; 00160 } 00161 //std::cout<<"============"<<std::endl; 00162 00163 // look if there is no intersection that all 00164 int is_intersection=0; 00165 for(int k=0;is_intersection==0 && k<size();k++) 00166 if(temp_type_edge[k]!=0) 00167 is_intersection=1; 00168 if(is_intersection==0)//no intersection 00169 { 00170 if(type!=0) 00171 *type=0; 00172 return intersections; 00173 } 00174 00175 00176 // look if there is only one vertex in common 00177 int is_two_intersection=0; 00178 int k_vertex=-1; 00179 for(int k=0;is_two_intersection==0 && k<size();k++) 00180 { 00181 if( temp_type_edge[k]==1 || temp_type_edge[k]==2) is_two_intersection=1; 00182 if( temp_type_edge[k]==2) k_vertex=k; 00183 } 00184 00185 if(is_two_intersection==0) 00186 { 00187 if(k_vertex==-1) 00188 { 00189 //printf("Error in Polygon in plane_intersection, types are not corrects\n"); 00190 if(type!=0) 00191 *type=0; 00192 return intersections;exit(-1);} 00193 if(type!=0) 00194 *type=2; 00195 intersections.add(v[k_vertex]); return intersections; 00196 } 00197 00198 00199 00200 // there is two intersections 00201 int k_1=0,k_2=0; 00202 for(k_1=0;k_1<size();k_1++){ 00203 for(k_2=k_1+1;k_2<size();k_2++){ 00204 if( (temp_type_edge[k_1]==1 || temp_type_edge[k_1]==2) && 00205 (temp_type_edge[k_2]==1 || temp_type_edge[k_2]==2) && 00206 (inter[k_1]!=inter[k_2]) 00208 ) 00209 { 00210 if(type!=0) 00211 *type=1; 00212 intersections.add(inter[k_1]); 00213 intersections.add(inter[k_2]); 00214 00215 //std::cout<<intersections<<std::endl; 00216 00217 return intersections; 00218 } 00219 } 00220 } 00221 00222 00223 //else probleme 00224 if(type!=0) 00225 *type=0; 00226 return intersections; 00227 00228 }


| MC_int_vector mesh_conv::MC_polygon::position | ( | const MC_v3d & | x | ) | const |
return the type of position of a vertex with respect to the polygon
Definition at line 470 of file MC_polygon.cpp.
References is_outside(), mesh_conv::MC_v3d_vector::norm(), segment(), mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
Referenced by barycentric_coordinates().
00471 { 00472 double epsilon=0.0001; 00473 int N=size(); 00474 for(int k=0;k<N;k++) 00475 if( (x-v[k]).norm()<epsilon ) 00476 return MC_int_vector (2,k); 00477 if(is_outside(x)==1) 00478 return MC_int_vector (3,-1); 00479 for(int k=0;k<N;k++) 00480 if(segment(k).is_belonging(x)==1) 00481 return MC_int_vector (1,k); 00482 00483 return MC_int_vector (0,-1); 00484 }


| std::pair< MC_v3d, std::pair< int, std::pair< int, double > > > mesh_conv::MC_polygon::projected_direction | ( | const MC_v3d & | x0, | |
| const MC_v3d & | d, | |||
| const MC_int_vector & | forbidden_edge = MC_int_vector(-1) | |||
| ) | const |
project a point in the given direction (coplanar to the polygon)
Definition at line 339 of file MC_polygon.cpp.
References mesh_conv::MC_int_vector::find(), mesh_conv::MC_matrix::inverted(), mesh_conv::MC_v3d_vector::norm(), normal(), mesh_conv::MC_v3d::normalized(), mesh_conv::MC_matrix::rotation_axis_to_axis(), and mesh_conv::MC_v3d_vector::size().
00340 { 00341 00342 00343 int type=0,sub_type=0;double relative=0.0; 00344 00345 MC_v3d d=_d.normalized(); 00346 double epsilon=0.00001; 00347 00348 //first get the polygon in 2D 00349 MC_matrix R=MC_matrix::rotation_axis_to_axis(normal(),MC_v3d(0,0,1)); 00350 00351 bool is_intersected=false; 00352 MC_v3d intersection; 00353 00354 MC_polygon poly_2d=R*(*this); 00355 MC_v3d c0_2d=MC_v3d(R*c0); 00356 MC_v3d d_2d=MC_v3d(R*d); 00357 00358 // direction equation 00359 // c0+t*d => ax+by=c 00360 double a=d_2d[1],b=-d_2d[0],c=a*c0_2d[0]+b*c0_2d[1]; 00361 00362 00363 int N=size(); 00364 for(int k_seg=0;k_seg<N;k_seg++) 00365 { 00366 if(forbidden_edge.find(k_seg)==-1) 00367 { 00368 00369 MC_v3d c_x0=poly_2d[k_seg]; 00370 MC_v3d c_x1=poly_2d[(k_seg+1)%N]; 00371 00372 double n_segment=(c_x0-c_x1).norm(); 00373 00374 MC_v3d d_c=c_x1-c_x0; 00375 00376 double ra=d_c[1],rb=-d_c[0],rc=ra*c_x0[0]+rb*c_x0[1]; 00377 double det=rb*a-b*ra; 00378 00379 if(abs(det)>epsilon)//parallel 00380 { 00381 double xi=(rb*c-rc*b)/det; 00382 double yi=(rc*a-ra*c)/det; 00383 00384 //if (xi,yi) in the positive sens 00385 if( (xi-c0_2d[0])*d_2d[0]+(yi-c0_2d[1])*d_2d[1] >0 ) 00386 { 00387 00388 // check if inside 00389 double proj=(xi-c_x0[0])*(c_x1[0]-c_x0[0])+(yi-c_x0[1])*(c_x1[1]-c_x0[1]); 00390 double n_xi=pow((xi-c_x0[0])*(xi-c_x0[0])+(yi-c_x0[1])*(yi-c_x0[1]),0.5); 00391 00392 if(proj>=epsilon && n_xi<=n_segment) 00393 { 00394 00395 00396 if(is_intersected==false || (is_intersected==true && (intersection-c0).norm()> 00397 pow((xi-c0_2d[0])*(xi-c0_2d[0])+(yi-c0_2d[1])*(yi-c0_2d[0]),0.5) ) ) 00398 { 00399 is_intersected = true; 00400 intersection = MC_v3d(R.inverted()*MC_v3d(xi,yi,c0_2d[2])); 00401 00402 00403 if(proj<epsilon) //vertex 0 00404 {type=0; sub_type=k_seg; relative=0.0;} 00405 else if(abs(proj-1)<epsilon) //vertex 1 00406 {type=0; sub_type=(k_seg+1)%N; relative=0.0;} 00407 else //edge 00408 {type=1; sub_type=k_seg; 00409 if(n_segment<epsilon) 00410 relative=0.0; 00411 else 00412 relative=n_xi/n_segment; 00413 } 00414 } 00415 } 00416 } 00417 } 00418 } 00419 } 00420 00421 if(is_intersected==false)//no intersection (point outside) 00422 {intersection=MC_v3d(-1,-1,-1);type=-1;sub_type=-1;relative=0.0;} 00423 00424 00425 std::pair <MC_v3d,std::pair<int,std::pair<int,double> > > res; 00426 res.first=intersection; 00427 res.second.first=type; 00428 res.second.second.first=sub_type; 00429 res.second.second.second=relative; 00430 return res; 00431 00432 }

| std::pair<MC_polygon,MC_matrix> mesh_conv::MC_polygon::rotate_to_plane | ( | const MC_v3d & | normal | ) | const |
rotate the polygon into a plane defined by its normal (if polygon is planar)
| MC_segment mesh_conv::MC_polygon::segment | ( | const int & | edge_number | ) | const |
get the segment of the given edge
Definition at line 231 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
Referenced by barycentric_coordinates(), plane_intersection(), and position().
00232 { 00233 int N=size(); 00234 if(edge_number<0 || edge_number>N) 00235 {std::cout<<"MC_triangle::segment("<<edge_number<<"),_k_edge has to be between 0 and "<<size()<<std::endl;exit(-1);} 00236 00237 return MC_segment(v[edge_number],v[(edge_number+1)%N]); 00238 }


| MC_v3d mesh_conv::MC_polygon::segment_intersection | ( | const MC_segment & | s, | |
| int * | type = 0 | |||
| ) | const |
segment_intersection
| s | the segment to intersect | |
| type | the type of intersection (default 0) |
_ no intersections (type 0)
_ triangle intersection on one interior point (type 1)
_ triangle intersection on a vertex of the Segment (type 2)
_ triangle is partly or totally inside the segment (type 3)
Definition at line 305 of file MC_polygon.cpp.
References is_inside(), and mesh_conv::MC_triangle::triangulate().
Referenced by mesh_conv::MC_mesh_index_vector::segment_intersection().
00306 { 00307 std::vector <MC_triangle> v_t = MC_triangle::triangulate(*this); 00308 int N=v_t.size(); 00309 for(int k=0;k<N;k++) 00310 { 00311 int temp_type=0; 00312 MC_v3d i=v_t[k].segment_intersection(s,&temp_type); 00313 00314 if(type!=0) 00315 *type=temp_type; 00316 00317 if(temp_type==1 || temp_type==2 || temp_type==3) 00318 if(is_inside(i)==1) 00319 return i; 00320 } 00321 00322 if(type!=0) 00323 *type=0; 00324 return MC_v3d(0,0,0); 00325 }


| std::pair< std::vector< MC_polygon >, std::pair< MC_mesh_index_vector, std::pair< MC_int_vector, MC_int_vector > > > mesh_conv::MC_polygon::subdivide_barycenter_mid_edge | ( | const MC_int_vector & | constraint_edges = MC_int_vector() |
) | const |
split the given polygon by linking barycenter to the consecutiv mid edges but with constraint on the given edge to not add extra mid edge
Creates only triangles excepted for the last one which links every mid_points
Works well for quads
Definition at line 660 of file MC_polygon.cpp.
References mesh_conv::MC_int_vector::add(), mesh_conv::MC_int_vector_vector::add(), mesh_conv::MC_v3d_vector::add(), barycenter(), mesh_conv::MC_mesh_index_vector::connectivity(), counter, mesh_conv::MC_int_vector::find(), mesh_conv::MC_mesh_index_vector::get_polygon(), mesh_conv::MC_int_vector::linspace(), mesh_conv::MC_v3d_vector::MC_v3d_vector(), mesh_conv::MC_mesh_index_vector::point_set(), mesh_conv::MC_v3d_vector::size(), mesh_conv::MC_int_vector::size(), mesh_conv::MC_v3d_vector::v, and mesh_conv::MC_v3d_vector::zeros().
Referenced by subdivide_mixed_mid_edge().
00661 { 00662 00663 MC_mesh_index_vector m; 00664 MC_int_vector extra_index; 00665 MC_int_vector edge; 00666 00667 // in case there is no constraint 00668 if(constraint_edges.size()==0) 00669 { 00670 extra_index=MC_int_vector::linspace(size()+1,2*size()); 00671 edge=MC_int_vector::linspace(0,size()-1); 00672 00673 m.point_set()=MC_v3d_vector(v)<<barycenter(); 00674 int N=size(); 00675 for(int k=0;k<N;++k) 00676 { 00677 MC_v3d x_middle=0.5*(v[k]+v[(k+1)%N]); 00678 m.point_set().add(x_middle); 00679 m.connectivity().add(MC_int_vector(N+1+(k+N+1)%N,N,N+1+k,(k+1)%N)); 00680 } 00681 00682 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) ); 00683 } 00684 00685 00686 00687 MC_v3d bar=barycenter(); 00688 m.point_set().add(v).add(bar); 00689 int N=size(); 00690 00691 MC_v3d_vector mid_point; 00692 MC_int_vector map_index_middle=MC_int_vector::zeros(N);int counter=0; 00693 for(int k=0;k<N;k++) 00694 { 00695 if(constraint_edges.find(k)==-1) 00696 { 00697 MC_v3d x=0.5*(v[k]+v[(k+1)%N]); 00698 mid_point.add(x); 00699 m.point_set().add(x); 00700 extra_index.add(N+1+counter); 00701 edge.add(k); 00702 00703 map_index_middle[k]=counter++; 00704 00705 } 00706 else 00707 { 00708 mid_point.add(MC_v3d(-1,-1,-1)); 00709 map_index_middle[k]=-1; 00710 } 00711 } 00712 00713 MC_polygon temp; 00714 for(int k=0;k<N;k++) 00715 { 00716 //classical quads 00717 if(constraint_edges.find(k)==-1 && constraint_edges.find((k-1)<0?N-1:k-1)==-1) 00718 m.connectivity().add(MC_int_vector(k,N+1+map_index_middle[k],N,N+1+map_index_middle[k-1>=0?k-1:map_index_middle.size()-1])); 00719 // previous ok but new one is a boundary 00720 else if(constraint_edges.find(k)!=-1 && constraint_edges.find((k-1)<0?N-1:k-1)==-1) 00721 { 00722 m.connectivity().add(MC_int_vector(k,N,N+1+map_index_middle[k-1>=0?k-1:map_index_middle.size()-1])); 00723 m.connectivity().add(MC_int_vector(k,(k+1)%N,N)); 00724 } 00725 // previous is boundary, but next is ok 00726 else if(constraint_edges.find(k)==-1 && constraint_edges.find((k-1)<0?N-1:k-1)!=-1) 00727 m.connectivity().add(MC_int_vector(k,N+1+map_index_middle[k],N)); 00728 // not ok, just triangle 00729 else if(constraint_edges.find(k)!=-1 && constraint_edges.find((k-1)<0?N-1:k-1)!=-1) 00730 m.connectivity().add(MC_int_vector(k,(k+1)%N,N)); 00731 } 00732 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) ); 00733 00734 }

| std::vector< MC_polygon > mesh_conv::MC_polygon::subdivide_barycenter_mid_edge_no_constraint | ( | ) | const [private] |
split the given polygon by linking barycenter to the middle edges
Creates only four vertices polygons
Works well for quads
Definition at line 514 of file MC_polygon.cpp.
References barycenter(), mesh_conv::MC_v3d_vector::resize(), mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
00515 { 00516 00517 MC_v3d barycenter; 00518 00519 // the new midpoints 00520 MC_v3d_vector mid_points; 00521 00522 // as much mid point as there is vertices in the polygon 00523 mid_points.resize(size()); 00524 00525 int k=0,N_mid_points=size(); 00526 for(k=0;k<N_mid_points;k++) 00527 { 00528 mid_points[k]=0.5*(v[k]+v[(k+1)%N_mid_points]); 00529 barycenter+=v[k]; 00530 } 00531 barycenter/=double(N_mid_points); 00532 00533 std::vector <MC_polygon> new_polygon(N_mid_points); 00534 00535 for(k=0;k<N_mid_points;k++) 00536 { 00537 new_polygon[k].add(v[k]); 00538 new_polygon[k].add(mid_points[k]); 00539 new_polygon[k].add(barycenter); 00540 new_polygon[k].add(mid_points[k-1>=0?k-1:N_mid_points-1]); 00541 } 00542 00543 return new_polygon; 00544 00545 }

| std::pair< std::vector< MC_polygon >, std::pair< MC_mesh_index_vector, std::pair< MC_int_vector, MC_int_vector > > > mesh_conv::MC_polygon::subdivide_mid_edge | ( | const MC_int_vector & | constraint_edges = MC_int_vector() |
) | const |
split the given polygon by linking consecutiv mid edges but with constraint on the given edge to not add extra mid edge
Creates only triangles excepted for the last one which links every mid_points Works well for triangles
Definition at line 548 of file MC_polygon.cpp.
References mesh_conv::MC_int_vector::add(), mesh_conv::MC_int_vector_vector::add(), mesh_conv::MC_v3d_vector::add(), mesh_conv::MC_mesh_index_vector::connectivity(), mesh_conv::MC_int_vector::find(), mesh_conv::MC_mesh_index_vector::get_polygon(), mesh_conv::MC_int_vector::linspace(), MC_polygon(), mesh_conv::MC_mesh_index_vector::point_set(), mesh_conv::MC_int_vector::resize(), mesh_conv::MC_v3d_vector::size(), mesh_conv::MC_int_vector::size(), mesh_conv::MC_int_vector::to_set(), and mesh_conv::MC_v3d_vector::v.
Referenced by subdivide_mixed_mid_edge().
00549 { 00550 // in case there is no constraint 00551 if(constraint_edges.size()==0) 00552 { 00553 MC_mesh_index_vector m; 00554 MC_int_vector extra_index=MC_int_vector::linspace(size(),2*size()-1); 00555 MC_int_vector edge=MC_int_vector::linspace(0,size()-1); 00556 00557 m.point_set()=v; 00558 int N=size(); 00559 for(int k=0;k<N;++k) 00560 { 00561 MC_v3d x_middle=0.5*(v[k]+v[(k+1)%N]); 00562 m.point_set().add(x_middle); 00563 } 00564 // all triangles excepted the last on linking the mid_points 00565 for(int k=0;k<N;++k) 00566 m.connectivity().add(MC_int_vector( (k+1)%N,N+(k+N+1)%N,N+k )); 00567 //last one linking every mid_points 00568 m.connectivity().add(MC_int_vector::linspace(0,N-1)+N); 00569 00570 00571 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) ); 00572 } 00573 if(static_cast<int>(constraint_edges.to_set().size())==size()-1) //only one non subdivided edge 00574 { 00575 //find the non subdivided edge 00576 MC_int_pair non_subdivided_edge; 00577 int N=size(); 00578 for(int k=0;k<N;++k) 00579 if(constraint_edges.find(k)==-1) 00580 non_subdivided_edge=MC_int_pair(k,(k+1)%N); 00581 MC_v3d x_middle=0.5*(v[non_subdivided_edge[0]]+v[non_subdivided_edge[1]]); 00582 00583 MC_int_vector extra_index(size()); 00584 MC_int_vector edge=non_subdivided_edge[0]; 00585 00586 MC_mesh_index_vector m; 00587 m.point_set()=v; 00588 m.point_set().add(x_middle); 00589 00590 std::vector <MC_polygon> v_polygon; 00591 for(int k=0;k<N;++k) 00592 { 00593 if(k!=non_subdivided_edge[0]) 00594 { 00595 MC_int_pair edge(k,(k+1)%N); 00596 v_polygon.push_back(MC_polygon(v[edge[0]],v[edge[1]],x_middle)); 00597 00598 m.connectivity().add(MC_int_vector(edge[0],edge[1],size())); 00599 } 00600 } 00601 return std::make_pair(v_polygon,std::make_pair(m,std::make_pair(extra_index,edge) ) ); 00602 } 00603 00604 //other case, only link the subdivided part 00605 MC_mesh_index_vector m; 00606 m.point_set()=v; 00607 00608 MC_int_vector new_index_contour; 00609 int N=size(); 00610 int k_new=0; 00611 MC_int_vector extra_index; 00612 MC_int_vector edge; 00613 for(int k=0;k<N;++k) 00614 { 00615 new_index_contour.add(k); 00616 if(constraint_edges.find(k)==-1) 00617 { 00618 extra_index.add(N+k_new); 00619 edge.add(k); 00620 new_index_contour.add(N+k_new); 00621 00622 m.point_set().add(0.5*(v[k]+v[(k+1)%N])); 00623 k_new++; 00624 } 00625 } 00626 if(extra_index.size()==0) 00627 { 00628 m.connectivity()=MC_int_vector::linspace(0,size()-1); 00629 00630 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) ); 00631 } 00632 00633 00634 //finish by the connectivity 00635 int N_new_points=m.point_set().size(); 00636 int k_current=new_index_contour.find(extra_index[0]); 00637 int k_current0=k_current; 00638 MC_int_vector temp_poly=MC_int_vector(new_index_contour[k_current]); 00639 00640 k_current=(k_current+1)%N_new_points; 00641 while(k_current!=k_current0) 00642 { 00643 temp_poly.add(new_index_contour[k_current]); 00644 if(extra_index.find(new_index_contour[k_current])!=-1) 00645 { 00646 m.connectivity().add(temp_poly); 00647 temp_poly.resize(0); 00648 temp_poly.add(new_index_contour[k_current]); 00649 } 00650 k_current=(k_current+1)%N_new_points; 00651 } 00652 temp_poly.add(new_index_contour[k_current0]); 00653 m.connectivity().add(temp_poly); 00654 00655 if(extra_index.size()>=3)//fill the middle 00656 m.connectivity().add(extra_index); 00657 00658 return std::make_pair(m.get_polygon(),std::make_pair(m,std::make_pair(extra_index,edge) ) ); 00659 }

| std::vector< MC_polygon > mesh_conv::MC_polygon::subdivide_mid_edge_no_constraint | ( | ) | const [private] |
split the given polygon by linking consecutiv edges
Creates only triangles excepted for the last one which links every mid_points
Works well for triangles
Definition at line 486 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::add(), MC_polygon(), mesh_conv::MC_v3d_vector::resize(), mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
00487 { 00488 // the new midpoints 00489 MC_v3d_vector mid_points; 00490 // as much mid point as there is vertices in the polygon 00491 mid_points.resize(size()); 00492 00493 int k=0,N_mid_points=size(); 00494 for(k=0;k<N_mid_points;k++) 00495 mid_points[k]=0.5*(v[k]+v[(k+1)%N_mid_points]); 00496 00497 // the new polygons 00498 std::vector <MC_polygon> new_polygon; 00499 // size of new_polygon = (old)N_vertex + 1 00500 new_polygon.resize(N_mid_points+1); 00501 00502 // all triangles excepted the last on linking the mid_points 00503 for(k=0;k<N_mid_points;k++) 00504 { 00505 new_polygon[k]=MC_polygon(mid_points[k],v[k],mid_points[k-1>=0?k-1:N_mid_points-1]); 00506 } 00507 //last one linking every mid_points 00508 for(k=0;k<N_mid_points;k++) 00509 new_polygon[N_mid_points].add(mid_points[k]); 00510 00511 00512 return new_polygon; 00513 }

| std::pair< std::vector< MC_polygon >, std::pair< MC_mesh_index_vector, std::pair< MC_int_vector, MC_int_vector > > > mesh_conv::MC_polygon::subdivide_mixed_mid_edge | ( | const MC_int_vector & | constraint_edges = MC_int_vector() |
) | const |
subdivision of vertices adapted to polygon type
Use subdivide_barycenter_mid_edge for size()>3 and subdivide_mid_edge for size()==3
Definition at line 735 of file MC_polygon.cpp.
References mesh_conv::MC_v3d_vector::size(), subdivide_barycenter_mid_edge(), and subdivide_mid_edge().
00736 { 00737 if(size()<3) 00738 {std::cout<<"Error in MC_polygon::subdivide_mixed_mid_edge(), polygon has size "<<size()<<std::endl;exit(-1);} 00739 if(size()==3) 00740 return subdivide_mid_edge(constraint_edges); 00741 else 00742 return subdivide_barycenter_mid_edge(constraint_edges); 00743 }

| std::pair< MC_polygon, std::pair< bool, bool > > mesh_conv::MC_polygon::undegenerated | ( | ) | const |
return a polygon not degenerated if possible
1.does the polygon has been changed
2.does the new polygon is valid
Definition at line 755 of file MC_polygon.cpp.
References MC_polygon(), mesh_conv::MC_v3d_vector::size(), and mesh_conv::MC_v3d_vector::v.
Referenced by mesh_conv::MC_mesh_index_vector::added_polygon_soup().
00756 { 00757 std::set <MC_v3d,MC_v3d_less> set_poly; 00758 int N=size(); 00759 std::pair <MC_polygon,std::pair <bool,bool> > new_pol(MC_polygon(),std::pair<bool,bool>(true,true)); 00760 for(int k=0;k<N;k++) 00761 if(set_poly.insert(v[k]).second==true) 00762 new_pol.first.add(v[k]); 00763 else 00764 new_pol.second.first=false; 00765 00766 if(new_pol.first.size()>=3) 00767 new_pol.second.second=true; 00768 else 00769 new_pol.second.second=false; 00770 00771 00772 return new_pol; 00773 }


1.6.1