00001
00002 #include <Polygon.h>
00003
00004 Polygon::Polygon() {x.resize(0);}
00005 Polygon::Polygon(const Polygon& poly) {x=poly.x;}
00006 Polygon::~Polygon() {destroy();}
00007
00008
00009 Polygon::Polygon(const V_3D& x0,const V_3D& x1,const V_3D& x2)
00010 {destroy();x.push_back(x0);x.push_back(x1);x.push_back(x2);}
00011 Polygon::Polygon(const V_3D& x0,const V_3D& x1,const V_3D& x2,const V_3D& x3)
00012 {destroy();x.push_back(x0);x.push_back(x1);x.push_back(x2);x.push_back(x3);}
00013 Polygon::Polygon(const std::vector <V_3D>& v)
00014 {set_polygon(v);}
00015
00016 int Polygon::destroy() {x.resize(0);return 0;}
00017 int Polygon::size() const {return x.size();}
00018
00019
00020 V_3D Polygon::operator()(int index) const
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 }
00025 V_3D& Polygon::operator()(int index)
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 }
00030 V_3D Polygon::operator[](int index) const
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 }
00035 V_3D& Polygon::operator[](int index)
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 }
00040
00041 int Polygon::set_polygon(const std::vector <V_3D>& v)
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
00047 x=v;
00048
00049 return 0;
00050 }
00051 int Polygon::set_polygon(const V_3D& x0,const V_3D& x1,const V_3D& x2)
00052 {
00053 destroy();
00054 x.push_back(x0);
00055 x.push_back(x1);
00056 x.push_back(x2);
00057 return 0;
00058 }
00059
00060 int Polygon::add_vertex(const V_3D& v)
00061 {x.push_back(v);return 0;}
00062 int Polygon::add_vertex(double x0,double x1,double x2)
00063 {V_3D temp(x0,x1,x2);x.push_back(temp);return 0;}
00064 int Polygon::add_vertex(const std::vector <V_3D>& v)
00065 {
00066 for(unsigned int k=0;k<v.size();k++)
00067 x.push_back(v[k]);
00068 return 0;
00069 }
00070
00071 std::vector <Polygon> Polygon::triangulate() const
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 }
00087 std::vector <Triangle> Polygon::get_triangulation() const
00088 {
00089 std::vector <Polygon> polygon_set=triangulate();
00090
00091
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 }
00097
00098 ostream& operator<<(ostream& stream,const Polygon& poly)
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 }
00105
00106 Polygon& Polygon::operator=(const Polygon& poly)
00107 {
00108 x = poly.x;
00109 return *this;
00110 }
00111
00112 V_3D Polygon::normal() const
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 }
00118
00119
00120 Triangle Polygon::to_triangle() const
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 }
00126
00127
00128 double Polygon::shortest_distance_to_point(const V_3D& _x) const
00129 {V_3D y=closest_point(_x);return (y-_x).norm();}
00130
00131 V_3D Polygon::closest_point(const V_3D& _x) const
00132 {int type=0;return closest_point(_x,&type);}
00133
00134 V_3D Polygon::closest_point(const V_3D& _x,int *type) const
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
00142 V_3D projection;
00143 projection = _x-((_x-x[0]).dot(n))*n;
00144
00145 std::vector <Triangle> triangles=get_triangulation();
00146
00147
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
00158
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
00179 for(int k=0;k<size();k++)
00180 if( (closest-x[k]).norm() < epsilon)
00181 *type=2;
00182 return closest;
00183 }
00184
00185 Segment Polygon::get_segment(int index) const
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 }
00193
00194
00195
00196 std::vector <V_3D> Polygon::plane_intersection(const V_3D& n,const V_3D& x0,int *type) const
00197 {std::vector <int> type_edge;return plane_intersection(n,x0,type,&type_edge);}
00198
00199 std::vector <V_3D> Polygon::plane_intersection(const V_3D& n,const V_3D& x0,int *type,std::vector <int> *type_edge) const
00200 {
00201
00202 std::vector <V_3D> intersections;
00203
00204
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
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)
00222 {*type=0;return intersections;}
00223
00224
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
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
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
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 }
00261
00262 Polygon Polygon::half_space_intersection(const V_3D& n,const V_3D& x0,int *type)
00263 {
00264
00265 std::vector <V_3D> intersection;
00266 int type_edges;
00267
00268 intersection = plane_intersection(n,x0,&type_edges);
00269
00270
00271 Polygon new_polygon;
00272 if(type_edges!=1)
00273 {
00274 if(((*this)[0]-x0).dot(n)<0)
00275 {
00276
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
00284 *type=0;
00285 return *this;
00286 }
00287 }
00288
00289
00290
00291 *type=1;
00292 Segment s(intersection[0],intersection[1]);
00293 V_3D old_normal=normal();
00294
00295
00296
00297
00298
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
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 }
00323
00324 std::vector <Polygon> Polygon::subdivide_mid_edge() const
00325 {
00326
00327 std::vector <V_3D> mid_points;
00328
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
00336 std::vector <Polygon> new_polygon;
00337
00338 new_polygon.resize(N_mid_points+1);
00339
00340
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
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 }
00354
00355
00356 std::vector <Polygon> Polygon::subdivide_barycenter_mid_edge() const
00357 {
00358
00359 V_3D barycenter;
00360
00361
00362 std::vector <V_3D> mid_points;
00363
00364
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 }
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412