00001 #ifndef polygonal_curve_H
00002 #define polygonal_curve_H
00003
00004 #include <fstream>
00005 #include <list>
00006 #include "polygon_edge.h"
00007 #include "rigid_motion.h"
00008
00009 namespace rescue
00010 {
00011
00012 template <class point>
00013 class polygon_edge;
00014
00015
00020
00021
00022 template <class point>
00023 class polygonal_curve
00024 {
00025
00026 public:
00027
00028 typedef point point_t;
00029 typedef point::arithmetic_t arithmetic_t;
00030 typedef arithmetic_t arithmetic;
00031
00032 typedef rigid_motion<arithmetic> motion;
00033 typedef int size_t;
00034 typedef polygon_vertex<point> vertex;
00035 typedef polygon_edge<point> edge;
00036
00037 class vertex_iterator
00038 {
00039
00040 protected:
00041
00042 vertex* position;
00043
00044 public:
00045
00046 inline vertex_iterator()
00047 {
00048 position = NULL;
00049 }
00050
00051 inline vertex_iterator(vertex* pos)
00052 {
00053 position = pos;
00054 }
00055
00056 inline vertex_iterator& operator++()
00057 {
00058 if (position!=NULL)
00059 position = position->next;
00060 return *this;
00061 }
00062
00063 inline vertex_iterator& operator++(int)
00064 {
00065 if (position!=NULL)
00066 position = position->next;
00067 return *this;
00068 }
00069
00070 inline vertex_iterator& operator--()
00071 {
00072 if (position!=NULL)
00073 position = position->prev;
00074 return *this;
00075 }
00076
00077 inline vertex_iterator& operator--(int)
00078 {
00079 if (position!=NULL)
00080 position = position->prev;
00081 return *this;
00082 }
00083
00084 inline vertex_iterator& operator=(const vertex_iterator& v_it)
00085 {
00086 position = v_it.position;
00087 return *this;
00088 }
00089
00090 inline vertex& operator*()
00091 {
00092 return *position;
00093 }
00094
00095 inline bool operator==(const vertex_iterator& v_it)
00096 {
00097 return position==v_it.position;
00098 }
00099
00100 inline bool operator!=(const vertex_iterator& v_it)
00101 {
00102 return position!=v_it.position;
00103 }
00104
00105 };
00106
00107
00108 class edge_iterator : public vertex_iterator
00109 {
00110
00111 public:
00112
00113 edge operator*()
00114 {
00115 return edge(*this);
00116 }
00117
00118 };
00119
00120 typedef vertex_iterator pc_vertex_iterator;
00121
00122 private:
00123
00124 vertex* first;
00125 vertex* last;
00126
00127 size_t curve_length;
00128
00129 public:
00130
00132 size_t length() {
00133 return curve_length-1;
00134 }
00135
00136
00140 polygonal_curve();
00141
00143 polygonal_curve(const polygonal_curve<point>& P, const int n);
00144
00146 polygonal_curve(const polygonal_curve<point>&);
00147
00150 polygonal_curve(const polygonal_curve<point>& P, vertex* one);
00151
00152 ~polygonal_curve();
00153
00155 polygonal_curve<point>& operator=(const polygonal_curve<point>&);
00156
00157 void clear();
00158
00159 void push_front(vertex* v);
00160 void push_back(vertex* v);
00161 void delete_last_point();
00162
00163 vertex_iterator vertex_begin() const;
00164 vertex_iterator vertex_end() const;
00165
00166 edge_iterator edge_begin();
00167 edge_iterator edge_end();
00168
00169 void read(std::fstream&);
00170 void write(std::fstream&);
00171
00172 polygonal_curve<point>& operator *= (const motion& m);
00173
00174 bool empty() { return first==NULL; }
00175
00176 };
00177
00178
00179
00180
00181
00182
00183
00184 template <class point>
00185 polygonal_curve<point>::polygonal_curve()
00186
00187 {
00188 curve_length = 0;
00189 first = NULL;
00190 last = NULL;
00191 }
00192
00193
00194 template <class point>
00195 polygonal_curve<point>::polygonal_curve(
00196 const polygonal_curve<point>& P,
00197 polygonal_curve<point>::vertex* one)
00198
00199 {
00200 *this = P;
00201 one->next = first->next;
00202 first = one;
00203 }
00204
00205
00206 template <class point>
00207 polygonal_curve<point>::polygonal_curve(
00208 const polygonal_curve<point>& P, const int n)
00209
00210 {
00211
00212 *this = P;
00213 int i=n;
00214 while (i>0 && first!=NULL)
00215 {
00216 first = first->next;
00217 curve_length--;
00218 i--;
00219 }
00220 if (first==NULL)
00221 last = NULL;
00222
00223 }
00224
00225
00226 template <class point>
00227 polygonal_curve<point>::polygonal_curve(
00228 const polygonal_curve<point>& P)
00229
00230 {
00231 vertex_iterator v_it = P.vertex_begin();
00232 for (; v_it!=P.vertex_end(); v_it++)
00233 push_back(new vertex((*v_it).pos()));
00234 }
00235
00236
00237 template <class point>
00238 polygonal_curve<point>& polygonal_curve<point>::operator=(
00239 const polygonal_curve<point>& P)
00240
00241 {
00242 clear();
00243 polygonal_curve<point>::vertex_iterator v_it = P.vertex_begin();
00244 for (; v_it!=P.vertex_end(); v_it++) {
00245 vertex v = *v_it;
00246 point pp = v.pos;
00247 this->push_back(new vertex(pp));
00248 }
00249 return *this;
00250 }
00251
00252
00253
00254 template <class point>
00255 polygonal_curve<point>::vertex_iterator
00256 polygonal_curve<point>::vertex_begin() const
00257
00258 {
00259 return polygonal_curve<point>::vertex_iterator(first);
00260 }
00261
00262
00263 template <class point>
00264 polygonal_curve<point>::vertex_iterator
00265 polygonal_curve<point>::vertex_end() const
00266
00267 {
00268 return polygonal_curve<point>::vertex_iterator(NULL);
00269 }
00270
00271
00272 template <class point>
00273 polygonal_curve<point>::edge_iterator
00274 polygonal_curve<point>::edge_begin()
00275
00276 {
00277 return polygonal_curve<point>::edge_iterator(first);
00278 }
00279
00280
00281 template <class point>
00282 polygonal_curve<point>::edge_iterator
00283 polygonal_curve<point>::edge_end()
00284
00285 {
00286 return polygonal_curve<point>::edge_iterator(last);
00287 }
00288
00289
00290 template <class point>
00291 void polygonal_curve<point>::push_front(polygonal_curve<point>::vertex* v)
00292
00293 {
00294 v->next = first;
00295 v->prev = NULL;
00296 if (first!=NULL)
00297 first->prev = v;
00298 first = v;
00299 curve_length++;
00300 }
00301
00302
00303 template <class point>
00304 void polygonal_curve<point>::push_back(polygonal_curve<point>::vertex* v)
00305
00306 {
00307
00308 if (curve_length>0)
00309 {
00310 v->prev = last;
00311 v->next = NULL;
00312 if (last!=NULL)
00313 last->next = v;
00314 last = v;
00315 curve_length++;
00316 } else {
00317 v->next = NULL;
00318 v->prev = NULL;
00319 first = v;
00320 last = v;
00321 curve_length = 1;
00322 }
00323
00324
00325 }
00326
00327
00328 template <class point>
00329 void polygonal_curve<point>::delete_last_point()
00330
00331 {
00332 if (curve_length>0)
00333 {
00334 vertex* temp = last;
00335 if (last!=NULL)
00336 {
00337 last = last->prev;
00338 if (last!=NULL)
00339 last->next = NULL;
00340 }
00341 delete temp;
00342 curve_length--;
00343 if (curve_length==0)
00344 {
00345 first = NULL;
00346 last = NULL;
00347 }
00348 }
00349 }
00350
00351
00352 template <class point>
00353 polygonal_curve<point>& polygonal_curve<point>::operator *= (const motion& m)
00354
00355 {
00356
00357 vertex_iterator v_it = vertex_begin();
00358 for (; v_it!=vertex_end(); v_it++)
00359 {
00360 (*v_it).pos *= m;
00361 }
00362
00363 return *this;
00364
00365 }
00366
00367
00368 template <class point>
00369 void polygonal_curve<point>::read(std::fstream& str)
00370
00371 {
00372
00373 clear();
00374
00375 size_t len;
00376 str.read((char*)&len,sizeof(size_t));
00377 vertex_iterator v_it = vertex_begin();
00378 for (int i=0; i<len; i++)
00379 {
00380 double xx;
00381 double yy;
00382 str.read((char*)&xx,sizeof(double));
00383 str.read((char*)&yy,sizeof(double));
00384 point p(xx,yy);
00385 push_back(new vertex(p));
00386 }
00387
00388 }
00389
00390
00391 template <class point>
00392 void polygonal_curve<point>::write(std::fstream& str)
00393
00394 {
00395
00396 str.write((char*)&curve_length,sizeof(size_t));
00397 vertex_iterator v_it = vertex_begin();
00398 for (; v_it!=vertex_end(); v_it++)
00399 {
00400
00401 point p = (*v_it).pos;
00402 double xx = p.x;
00403 double yy = p.y;
00404 str.write((char*)&xx,sizeof(double));
00405 str.write((char*)&yy,sizeof(double));
00406
00407 }
00408
00409 }
00410
00411
00412 template <class point>
00413 void polygonal_curve<point>::clear()
00414
00415 {
00416
00417 vertex_iterator v_it = vertex_begin();
00418 vertex* prev = NULL;
00419 for (; v_it!=vertex_end(); v_it++)
00420 {
00421 if (prev!=NULL)
00422 delete prev;
00423 prev = &(*v_it);
00424 }
00425 if (prev!=NULL)
00426 delete prev;
00427
00428 curve_length = 0;
00429 first = NULL;
00430 last = NULL;
00431
00432 }
00433
00434
00435 template <class point>
00436 polygonal_curve<point>::~polygonal_curve()
00437
00438 {
00439 clear();
00440 }
00441
00442
00443 }
00444
00445 #endif