Polygon Class Reference

Manipulation class for a Polygon. More...

#include <Polygon.h>

Collaboration diagram for Polygon:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 Polygon ()
 Classical constructor.
 Polygon (const V_3D &x0, const V_3D &x1, const V_3D &x2)
 Constructor for triangle.
 Polygon (const V_3D &x0, const V_3D &x1, const V_3D &x2, const V_3D &x3)
 Constructor for quad.
 Polygon (const std::vector< V_3D > &v)
 Constructor for any Polygon.
 Polygon (const Polygon &poly)
 Copy Constructor.
 ~Polygon ()
 destructor
int size () const
 get the number of edges
Segment get_segment (int index) const
 get an edge as a segment
int destroy ()
 destroy the polygon
int set_polygon (const std::vector< V_3D > &v)
 set a arbitrary polygon
int set_polygon (const V_3D &x0, const V_3D &x1, const V_3D &x2)
 set a triangle
int add_vertex (const V_3D &v)
 add a vertex
int add_vertex (double x0, double x1, double x2)
 add a vertex
int add_vertex (const std::vector< V_3D > &v)
 add a set of vertex
std::vector< Polygontriangulate () const
 triangulate the given polygon as a fan
std::vector< Triangleget_triangulation () const
 triangulate the given polygon as a fan
V_3D normal () const
 get normal to the polygon
Triangle to_triangle () const
 if the polygon has only three vertices, convert it to triangle
double shortest_distance_to_point (const V_3D &x) const
 get shortest distance between point and the polygon
V_3D closest_point (const V_3D &x, int *type) const
 get shortest position on the polygon between the polygon and the point
V_3D closest_point (const V_3D &x) const
 get shortest position on the polygon between the polygon and the point(no type information)
V_3D closest_segment_point (const Segment &s) const
 get closest point of the polygon in the segment
std::vector< V_3Dplane_intersection (const V_3D &n, const V_3D &x0, int *type) const
 Intersection with the plane of equation <n,x-x0>=0.
std::vector< V_3Dplane_intersection (const V_3D &n, const V_3D &x0, int *type, std::vector< int > *type_edge) const
 Intersection with the plane of equation <n,x-x0>=0.
Polygon half_space_intersection (const V_3D &n, const V_3D &x0, int *type)
 Return the intersection of the polygon and the half space defined by the oriented plane <n,x-x0>=0.
std::vector< Polygonsubdivide_mid_edge () const
 split the given polygon by linking consecutiv edges
std::vector< Polygonsubdivide_barycenter_mid_edge () const
 split the given polygon by linking barycenter to the middle edges
V_3D operator() (int index) const
 get the vertex
V_3Doperator() (int index)
 get the vertex
V_3D operator[] (int index) const
 get the vertex
V_3Doperator[] (int index)
 get the vertex
Polygonoperator= (const Polygon &)
 operator =

Private Attributes

std::vector< V_3Dx

Friends

ostream & operator<< (ostream &flux, const Polygon &_v)
 output


Detailed Description

Manipulation class for a Polygon.

Calculation for embedeed polygon. The polygon has to be plane and oriented. The polygon has to be convex in order to be triangulated as a fan.

Definition at line 46 of file Polygon.h.


Constructor & Destructor Documentation

Polygon::Polygon (  ) 

Classical constructor.

Definition at line 4 of file Polygon.cpp.

References x.

00004 {x.resize(0);}

Polygon::Polygon ( const V_3D x0,
const V_3D x1,
const V_3D x2 
)

Constructor for triangle.

Definition at line 9 of file Polygon.cpp.

References destroy(), and x.

00010 {destroy();x.push_back(x0);x.push_back(x1);x.push_back(x2);}

Here is the call graph for this function:

Polygon::Polygon ( const V_3D x0,
const V_3D x1,
const V_3D x2,
const V_3D x3 
)

Constructor for quad.

Definition at line 11 of file Polygon.cpp.

References destroy(), and x.

00012 {destroy();x.push_back(x0);x.push_back(x1);x.push_back(x2);x.push_back(x3);}

Here is the call graph for this function:

Polygon::Polygon ( const std::vector< V_3D > &  v  ) 

Constructor for any Polygon.

Definition at line 13 of file Polygon.cpp.

References set_polygon().

00014 {set_polygon(v);}

Here is the call graph for this function:

Polygon::Polygon ( const Polygon poly  ) 

Copy Constructor.

Definition at line 5 of file Polygon.cpp.

References x.

00005 {x=poly.x;}

Polygon::~Polygon (  ) 

destructor

Definition at line 6 of file Polygon.cpp.

References destroy().

00006 {destroy();}

Here is the call graph for this function:


Member Function Documentation

int Polygon::size (  )  const

Segment Polygon::get_segment ( int  index  )  const

get an edge as a segment

Definition at line 185 of file Polygon.cpp.

References size(), and x.

Referenced by plane_intersection().

00186 {
00187   if(index<0 || index>=size())
00188     {printf("Error in get_segment(%d) in Polygon, size=%d\n",index,size());exit(-1);}
00189 
00190   Segment s(x[index],x[(index+1)%size()]);
00191   return s;
00192 }

Here is the call graph for this function:

Here is the caller graph for this function:

int Polygon::destroy (  ) 

destroy the polygon

Definition at line 16 of file Polygon.cpp.

References x.

Referenced by Polygon(), set_polygon(), and ~Polygon().

00016 {x.resize(0);return 0;}

Here is the caller graph for this function:

int Polygon::set_polygon ( const std::vector< V_3D > &  v  ) 

set a arbitrary polygon

Definition at line 41 of file Polygon.cpp.

References x.

Referenced by Polygon().

00042 {
00043   if(v.size()<=2)
00044     {printf("Error in set_polygon in Polygon, size of given polygon=%d < 3\n",v.size());exit(-1);}
00045 
00046   //copy the vector
00047   x=v;
00048 
00049   return 0;
00050 }

Here is the caller graph for this function:

int Polygon::set_polygon ( const V_3D x0,
const V_3D x1,
const V_3D x2 
)

set a triangle

Definition at line 51 of file Polygon.cpp.

References destroy(), and x.

00052 {
00053   destroy();
00054   x.push_back(x0);
00055   x.push_back(x1);
00056   x.push_back(x2);
00057   return 0;
00058 }

Here is the call graph for this function:

int Polygon::add_vertex ( const V_3D v  ) 

add a vertex

Definition at line 60 of file Polygon.cpp.

References x.

Referenced by half_space_intersection(), and subdivide_mid_edge().

00061 {x.push_back(v);return 0;}

Here is the caller graph for this function:

int Polygon::add_vertex ( double  x0,
double  x1,
double  x2 
)

add a vertex

Definition at line 62 of file Polygon.cpp.

References x.

00063 {V_3D temp(x0,x1,x2);x.push_back(temp);return 0;}

int Polygon::add_vertex ( const std::vector< V_3D > &  v  ) 

add a set of vertex

Definition at line 64 of file Polygon.cpp.

References x.

00065 {
00066   for(unsigned int k=0;k<v.size();k++)
00067     x.push_back(v[k]);
00068   return 0;
00069 }

std::vector< Polygon > Polygon::triangulate (  )  const

triangulate the given polygon as a fan

return as may triangle polygons as needed to triangulate this one

Definition at line 71 of file Polygon.cpp.

References size(), and x.

Referenced by get_triangulation().

00072 {
00073   int N_triangle=size()-2;
00074   std::vector <Polygon> vector_triangle(N_triangle);
00075 
00076   if(N_triangle<=0)
00077     {printf("Error in triangulate in Polygon, size of current polygon (%d) is not enough\n",size());exit(-1);}
00078 
00079   for(int k_tri=0;k_tri<N_triangle;k_tri++)
00080     {
00081       vector_triangle[k_tri].add_vertex(x[0]);
00082       vector_triangle[k_tri].add_vertex(x[k_tri+1]);
00083       vector_triangle[k_tri].add_vertex(x[k_tri+2]);
00084     }
00085   return vector_triangle;
00086 }

Here is the call graph for this function:

Here is the caller graph for this function:

std::vector< Triangle > Polygon::get_triangulation (  )  const

triangulate the given polygon as a fan

return as may Triangle as needed to triangulate this one

Definition at line 87 of file Polygon.cpp.

References triangulate().

Referenced by closest_point().

00088 {
00089   std::vector <Polygon> polygon_set=triangulate();
00090 
00091   // convert polygon to triangles
00092   std::vector <Triangle> triangle_set;
00093   for(unsigned int k=0;k<polygon_set.size();k++)
00094     triangle_set.push_back(polygon_set[k].to_triangle());
00095   return triangle_set;
00096 }

Here is the call graph for this function:

Here is the caller graph for this function:

V_3D Polygon::normal (  )  const

get normal to the polygon

Definition at line 112 of file Polygon.cpp.

References size(), and x.

Referenced by closest_point(), OpenGL_drawer::draw_polygon(), and half_space_intersection().

00113 {
00114   if(size()<=2){printf("Error in normal() in Polygon, Polygon size is not ok [%d]\n",size());exit(-1);}
00115   V_3D n = ((x[1]-x[0]).vector_prod(x[2]-x[0])).normalized();
00116   return n;
00117 }

Here is the call graph for this function:

Here is the caller graph for this function:

Triangle Polygon::to_triangle (  )  const

if the polygon has only three vertices, convert it to triangle

Definition at line 120 of file Polygon.cpp.

References size(), and x.

00121 {
00122   if(size()!=3){printf("Error in to_triangle, in Polygon, size is != 3 (%d)\n",size());exit(-1);}
00123   Triangle t(x[0],x[1],x[2]);
00124   return t;
00125 }

Here is the call graph for this function:

double Polygon::shortest_distance_to_point ( const V_3D x  )  const

get shortest distance between point and the polygon

Definition at line 128 of file Polygon.cpp.

References closest_point().

Referenced by Mesh_object::closest_mesh_point().

00129 {V_3D y=closest_point(_x);return (y-_x).norm();}

Here is the call graph for this function:

Here is the caller graph for this function:

V_3D Polygon::closest_point ( const V_3D x,
int *  type 
) const

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

return in type the type of point 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 134 of file Polygon.cpp.

References Segment::closest_point(), Segment::distance_to_point(), get_triangulation(), normal(), Segment::set(), size(), and x.

Referenced by Mesh_object::closest_mesh_point(), closest_point(), and shortest_distance_to_point().

00135 {
00136   if(size()<=2){printf("Error in closest_polygon_point in Polygon, Polygon size is not ok [%d]\n",size());exit(-1);}
00137 
00138   double epsilon=0.00001;
00139   V_3D n = normal();
00140 
00141   // get the projection on the plane
00142   V_3D projection;
00143   projection = _x-((_x-x[0]).dot(n))*n;
00144   
00145   std::vector <Triangle> triangles=get_triangulation();
00146   
00147   // first, try to find if the projection is inside the polygon (in one of the triangle)
00148   for(unsigned int k=0;k<triangles.size();k++)
00149     {
00150       if(triangles[k].is_vertex_inside(projection)==1)
00151         {
00152           *type=0;
00153           return projection;
00154         }
00155     }
00156   
00157   // then, the projection is outside the polygon
00158   // find the closest edge
00159   V_3D x0,x1,closest;Segment s;double L=0.0,L_min=9999.9;
00160   int closest_edge=-1;
00161   for(int k=0;k<size();k++)
00162     {
00163       x0 = x[k];
00164       x1 = x[(k+1)%size()];
00165       s.set(x0,x1);
00166       
00167       L = s.distance_to_point(projection);
00168       if(L<L_min)
00169         {
00170           closest = s.closest_point(projection);
00171           closest_edge = k;
00172           L_min=L;
00173         }
00174     }
00175 
00176 
00177   *type = 1;
00178   //look if the closest point is inside an edge, or a vertex
00179   for(int k=0;k<size();k++)
00180     if( (closest-x[k]).norm() < epsilon) //then it is close to a vertex
00181       *type=2;
00182   return closest;
00183 }

Here is the call graph for this function:

Here is the caller graph for this function:

V_3D Polygon::closest_point ( const V_3D x  )  const

get shortest position on the polygon between the polygon and the point(no type information)

Definition at line 131 of file Polygon.cpp.

References closest_point().

00132 {int type=0;return closest_point(_x,&type);}

Here is the call graph for this function:

V_3D Polygon::closest_segment_point ( const Segment s  )  const

get closest point of the polygon in the segment

two possiblities: 1. The segment crosses the polygon => the closest point is inside the polygon 2. The segment does not cross it => the closes point is in the edge

std::vector< V_3D > Polygon::plane_intersection ( const V_3D n,
const V_3D x0,
int *  type 
) const

Intersection with the plane of equation <n,x-x0>=0.

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

Definition at line 196 of file Polygon.cpp.

Referenced by half_space_intersection(), plane_intersection(), and Mesh_object::plane_intersection().

00197 {std::vector <int> type_edge;return plane_intersection(n,x0,type,&type_edge);}

Here is the caller graph for this function:

std::vector< V_3D > Polygon::plane_intersection ( const V_3D n,
const V_3D x0,
int *  type,
std::vector< int > *  type_edge 
) const

Intersection with the plane of equation <n,x-x0>=0.

Same as plane_intersection function, but with the detailed type intersection for each edge

Definition at line 199 of file Polygon.cpp.

References get_segment(), plane_intersection(), size(), and x.

00200 {
00201 
00202   std::vector <V_3D> intersections;
00203 
00204   // First, take every intersection with every segment
00205 
00206   std::vector <Segment> s;
00207   std::vector <V_3D> inter;
00208   type_edge->resize(size());
00209   for(int k=0;k<size();k++)
00210     {
00211       s.push_back(get_segment(k));
00212       inter.push_back(s[k].plane_intersection(n,x0,&((*type_edge)[k])));
00213     }
00214 
00215   
00216   // look if there is no intersection that all
00217   int is_intersection=0;
00218   for(int k=0;is_intersection==0 && k<size();k++)
00219     if((*type_edge)[k]!=0)
00220       is_intersection=1;
00221   if(is_intersection==0)//no intersection
00222     {*type=0;return intersections;}
00223 
00224   // look if there is a parralel edge
00225   for(int k=0;k<size();k++)
00226     if((*type_edge)[k]==3)
00227       {*type=3;intersections.push_back(s[k][0]);intersections.push_back(s[k][1]);return intersections;}
00228 
00229   // look if there is only one vertex in common
00230   int is_two_intersection=0;
00231   int k_vertex=-1;
00232   for(int k=0;is_two_intersection==0 && k<size();k++)
00233     {
00234       if( (*type_edge)[k]==1) is_two_intersection=1;
00235       if( (*type_edge)[k]==2) k_vertex=k;
00236     }
00237   if(is_two_intersection==0)
00238     {
00239       if(k_vertex==-1)
00240         {printf("Error in Polygon in plane_intersection, types are not corrects\n");exit(-1);}
00241       *type=2; intersections.push_back(x[k_vertex]); return intersections;
00242     }
00243   
00244 
00245   // there is two intersections
00246   int k_1=0,k_2=0;
00247   for(k_1=0;k_1<size();k_1++)
00248     for(k_2=k_1+1;k_2<size();k_2++)
00249       if( ((*type_edge)[k_1]==1||(*type_edge)[k_1]==2) && ((*type_edge)[k_2]==1||(*type_edge)[k_2]==2) )
00250         {*type=1;intersections.push_back(inter[k_1]);intersections.push_back(inter[k_2]);return intersections;}
00251 
00252 
00253   //else probleme
00254   cout<<"Error in plane_intersection("<<n<<","<<x0<<") ";
00255   printf("in Polygon, types are not correct: (");
00256   for(int k=0;k<size()-1;k++)
00257     printf("%d,",(*type_edge)[k]);
00258   printf("%d)\n",(*type_edge)[size()-1]);
00259   exit(-1);
00260 }

Here is the call graph for this function:

Polygon Polygon::half_space_intersection ( const V_3D n,
const V_3D x0,
int *  type 
)

Return the intersection of the polygon and the half space defined by the oriented plane <n,x-x0>=0.

3 Possibilies for type: 0 - unchanged polygon 1 - partly cutted polygon 2 - no more polygon at all

Definition at line 262 of file Polygon.cpp.

References add_vertex(), normal(), plane_intersection(), and size().

Referenced by Mesh_object::half_space_intersection().

00263 {
00264   //first take the intersection of the polygon and the plane
00265   std::vector <V_3D> intersection;
00266   int type_edges;
00267   
00268   intersection = plane_intersection(n,x0,&type_edges);
00269 
00270   //check if we need to cut or not the polygon
00271   Polygon new_polygon;
00272   if(type_edges!=1) // no change or just destroy the polygon
00273     {
00274       if(((*this)[0]-x0).dot(n)<0)//check the orientation of the polygon to the plane
00275         {
00276           //negativ so there is no more polygons
00277           *type=2;
00278           new_polygon.add_vertex(V_3D(-1.0,-1.0,-1.0));
00279           return new_polygon;
00280         }
00281       else
00282         {
00283           // the polygon is unchanged
00284           *type=0;
00285           return *this;
00286         }
00287     }
00288 
00289   //else there is a modification to bring to the polygon
00290 
00291   *type=1;
00292   Segment s(intersection[0],intersection[1]);
00293   V_3D old_normal=normal();
00294 
00295   //first add every points in the correct half space
00296   //(just to be sure that we know the vertex before the line)
00297 
00298   //find the first vertex in half space
00299   int k=0;
00300   while(((*this)[k]-x0).dot(n)<0)
00301     k++;
00302   int k_2=k;
00303 
00304   int added_line=0;
00305   do
00306     {
00307       if( ((*this)[k_2]-x0).dot(n)>0 )
00308         new_polygon.add_vertex((*this)[k_2]);
00309       else if(added_line==0)
00310         {
00311           // check if the line is in the right sense (we are sure that (*this[k2-1] already exists))
00312           if( ((s[1]-s[0]).vector_prod(s[0]-(*this)[(k_2-1)<0?size()-1:k_2-1])).dot(old_normal)<0)
00313             {new_polygon.add_vertex(s[0]);new_polygon.add_vertex(s[1]);}     
00314           else{new_polygon.add_vertex(s[1]);new_polygon.add_vertex(s[0]);}
00315           added_line=1;
00316         }
00317       k_2=(k_2+1)%size();
00318     }while(k_2!=k);
00319   
00320   return new_polygon;
00321   
00322 }

Here is the call graph for this function:

Here is the caller graph for this function:

std::vector< Polygon > Polygon::subdivide_mid_edge (  )  const

split the given polygon by linking consecutiv edges

Return 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 324 of file Polygon.cpp.

References add_vertex(), size(), and x.

Referenced by Mesh_object::subdivide_mid_edge(), and Mesh_object::subdivide_mixed_mid_edge().

00325 {
00326   // the new midpoints
00327   std::vector <V_3D> mid_points;
00328   // as much mid point as there is vertices in the polygon
00329   mid_points.resize(size());
00330 
00331   int k=0,N_mid_points=size();
00332   for(k=0;k<N_mid_points;k++)
00333     mid_points[k]=0.5*(x[k]+x[(k+1)%N_mid_points]);
00334 
00335   // the new polygons
00336   std::vector <Polygon> new_polygon;
00337   // size of new_polygon = (old)N_vertex + 1
00338   new_polygon.resize(N_mid_points+1);
00339 
00340   // all triangles excepted the last on linking the mid_points
00341   for(k=0;k<N_mid_points;k++)
00342     {
00343       new_polygon[k].add_vertex(x[k]);
00344       new_polygon[k].add_vertex(mid_points[k]);
00345       new_polygon[k].add_vertex(mid_points[k-1>=0?k-1:N_mid_points-1]);
00346     }
00347   //last one linking every mid_points
00348   for(k=0;k<N_mid_points;k++)
00349     new_polygon[N_mid_points].add_vertex(mid_points[k]);
00350 
00351   
00352   return new_polygon;
00353 }

Here is the call graph for this function:

Here is the caller graph for this function:

std::vector< Polygon > Polygon::subdivide_barycenter_mid_edge (  )  const

split the given polygon by linking barycenter to the middle edges

Return the set of new polygons Creates only four vertices polygons Works well for quads

Definition at line 356 of file Polygon.cpp.

References size(), and x.

Referenced by Mesh_object::subdivide_barycenter_mid_edge(), and Mesh_object::subdivide_mixed_mid_edge().

00357 {
00358 
00359   V_3D barycenter;
00360 
00361   // the new midpoints
00362   std::vector <V_3D> mid_points;
00363 
00364   // as much mid point as there is vertices in the polygon
00365   mid_points.resize(size());
00366 
00367   int k=0,N_mid_points=size();
00368   for(k=0;k<N_mid_points;k++)
00369     {
00370       mid_points[k]=0.5*(x[k]+x[(k+1)%N_mid_points]);
00371       barycenter+=x[k];
00372     }
00373   barycenter/=double(N_mid_points);
00374 
00375   std::vector <Polygon> new_polygon(N_mid_points);
00376   
00377     for(k=0;k<N_mid_points;k++)
00378     {
00379       new_polygon[k].add_vertex(x[k]);
00380       new_polygon[k].add_vertex(mid_points[k]);
00381       new_polygon[k].add_vertex(barycenter);
00382       new_polygon[k].add_vertex(mid_points[k-1>=0?k-1:N_mid_points-1]);
00383     }
00384 
00385     return new_polygon;
00386 }

Here is the call graph for this function:

Here is the caller graph for this function:

V_3D Polygon::operator() ( int  index  )  const

get the vertex

Definition at line 20 of file Polygon.cpp.

References size(), and x.

00021 {
00022   if(index<0 || index>size()){printf("Error in Polygon(%d) size of polygon=%d\n",index,size());exit(-1);}
00023   return x[index];
00024 }

Here is the call graph for this function:

V_3D & Polygon::operator() ( int  index  ) 

get the vertex

Definition at line 25 of file Polygon.cpp.

References size(), and x.

00026 {
00027   if(index<0 || index>size()){printf("Error in Polygon(%d) size of polygon=%d\n",index,size());exit(-1);}
00028   return x[index];
00029 }

Here is the call graph for this function:

V_3D Polygon::operator[] ( int  index  )  const

get the vertex

Definition at line 30 of file Polygon.cpp.

References size(), and x.

00031 {
00032   if(index<0 || index>size()){printf("Error in Polygon[%d] size of polygon=%d\n",index,size());exit(-1);}
00033   return x[index];
00034 }

Here is the call graph for this function:

V_3D & Polygon::operator[] ( int  index  ) 

get the vertex

Definition at line 35 of file Polygon.cpp.

References size(), and x.

00036 {
00037   if(index<0 || index>size()){printf("Error in Polygon[%d] size of polygon=%d\n",index,size());exit(-1);}
00038   return x[index];
00039 }

Here is the call graph for this function:

Polygon & Polygon::operator= ( const Polygon poly  ) 

operator =

Definition at line 106 of file Polygon.cpp.

References x.

00107 {
00108   x = poly.x;
00109   return *this;
00110 }


Friends And Related Function Documentation

ostream& operator<< ( ostream &  flux,
const Polygon _v 
) [friend]

output

Definition at line 98 of file Polygon.cpp.

00099 {
00100   int N_vertex=poly.size();
00101   for(int k_vertex=0;k_vertex<N_vertex;k_vertex++)
00102     stream<<poly[k_vertex]<<endl;
00103   return stream;
00104 }


Member Data Documentation

std::vector<V_3D> Polygon::x [private]


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

Generated on Mon Mar 30 16:58:16 2009 by  doxygen 1.5.6