mesh_conv::MC_polygon Class Reference

Container class for a polygon. More...

#include <MC_polygon.hpp>

Inheritance diagram for mesh_conv::MC_polygon:
Inheritance graph
[legend]
Collaboration diagram for mesh_conv::MC_polygon:
Collaboration graph
[legend]

List of all members.

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_matrixrotate_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_polygonsubdivide_mid_edge_no_constraint () const
 split the given polygon by linking consecutiv edges
std::vector< MC_polygonsubdivide_barycenter_mid_edge_no_constraint () const
 split the given polygon by linking barycenter to the middle edges

Detailed Description

Container class for a polygon.

Internal structure is a vector of MC_v3d

Definition at line 38 of file MC_polygon.hpp.


Constructor & Destructor Documentation

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     {}

Here is the caller graph for this function:

mesh_conv::MC_polygon::MC_polygon ( const MC_v3d v0,
const MC_v3d v1,
const MC_v3d v2 
)

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  ) 

copy constructor

Definition at line 71 of file MC_polygon.cpp.

00072             :MC_v3d_vector(vec)
00073     {}

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;}


Member Function Documentation

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();}

Here is the call graph for this function:

Here is the caller graph for this function:

MC_double_vector mesh_conv::MC_polygon::barycentric_coordinates ( const MC_v3d x  )  const

get the generalized barycentric coordinates

Warning:
x must be inside the polygon

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     }

Here is the call graph for this function:

Here is the caller graph for this function:

MC_v3d mesh_conv::MC_polygon::closest_point ( const MC_v3d x,
int *  type = 0 
) const

get shortest position on the polygon between the polygon and the point

Returns:
the closest 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     }

Here is the call graph for this function:

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

Parameters:
n the normal of the intersecting-plane
x0 a point on the plane
type for the type of intersection (default 0)
Returns:
a polygon resulting of the intersection

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     }

Here is the call graph for this function:

Here is the caller graph for this function:

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     }

Here is the call graph for this function:

Here is the caller graph for this function:

bool mesh_conv::MC_polygon::is_inside ( const MC_v3d _x  )  const

check if a vertex (in plane) is inside the polygon

Returns:
true if inside, false outside

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     }

Here is the call graph for this function:

Here is the caller graph for this function:

bool mesh_conv::MC_polygon::is_outside ( const MC_v3d _x  )  const

check if a vertex (in plane) is outside the polygon

Returns:
true if outside, false inside

Definition at line 336 of file MC_polygon.cpp.

References is_inside().

Referenced by position().

00337     {return !is_inside(_x);}

Here is the call graph for this function:

Here is the caller graph for this function:

bool mesh_conv::MC_polygon::is_planar (  )  const

check if the polygon is planar.

Returns:
false if not planar, true if 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     }

Here is the call graph for this function:

MC_v3d mesh_conv::MC_polygon::normal (  )  const

get the normal of the polygon (assume it is almost planar).

Returns:
the normal as a R3 vector.

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     }

Here is the call graph for this function:

Here is the caller graph for this function:

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.

Parameters:
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     }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Returns:
(0,-1) inside the polygon, (1,k_edge) on an edge, (2,k_vertex) on a vertex, (3,-1) not in 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     }

Here is the call graph for this function:

Here is the caller graph for this function:

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)

Warning:
, the direction must be coplanar to the polygon
Returns:
the position of the projected point, its type and its relative coordinates
V_3D: position in 3D space
1st int: type (0=vertex, 1=edge, -1=no_intersection)
2nd int: vertex/edge number in the polygon (-1=no_intersection)
double : relative position (0 for edge, interpolation for edge)

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     }

Here is the call graph for this function:

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)

Returns:
the new polygon
the matrix of rotation
Note:
the matrix is not unique (twist around the normal)
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     }

Here is the call graph for this function:

Here is the caller graph for this function:

MC_v3d mesh_conv::MC_polygon::segment_intersection ( const MC_segment s,
int *  type = 0 
) const

segment_intersection

Parameters:
s the segment to intersect
type the type of intersection (default 0)
Returns:
the point of intersection if it exist (else defaut value)

_ 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     }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Returns:
std::vector <MC_polygon> the vector of new polygons
MC_mesh_index the mesh corresponding to the complete polygons
MC_int_vector the index of the added vertices (barycenter added anyway at position size())
MC_int_vector the original edge corresponding to the newly created indices

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     }

Here is the caller graph for this function:

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

Returns:
Return the set of new polygons

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     }

Here is the call graph for this function:

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

Returns:
std::vector <MC_polygon> the vector of new polygons
MC_mesh_index the mesh corresponding to the complete polygons
MC_int_vector the index of the added vertices
MC_int_vector the original edge corresponding to the newly created indices

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     }

Here is the caller graph for this function:

std::vector< MC_polygon > mesh_conv::MC_polygon::subdivide_mid_edge_no_constraint (  )  const [private]

split the given polygon by linking consecutiv edges

Returns:
eturn the set of new polygons

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     }

Here is the call graph for this function:

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     }

Here is the call graph for this function:

std::pair< MC_polygon, std::pair< bool, bool > > mesh_conv::MC_polygon::undegenerated (  )  const

return a polygon not degenerated if possible

Returns:
the new undegenerated polygon and a set of indicators:

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     }

Here is the call graph for this function:

Here is the caller graph for this function:


The documentation for this class was generated from the following files:

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