00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef _SEGMENTATION_TOOLS_
00010 #define _SEGMENTATION_TOOLS_
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "Tools/Math/Geometry.h"
00021 #include "Tools/Math/Vector2.h"
00022 #include "Tools/ColorClasses.h"
00023
00024 typedef Vector2<int> point;
00025 typedef Vector2<double> direction;
00026
00027 struct LinePair2;
00028
00029
00030
00031
00032
00033
00034 inline point mil(point& v1,point& v2) {
00035 return point ((v1.x+v2.x) / 2,(v1.y+v2.y) / 2);
00036 };
00037
00038
00039
00040
00041 inline double theta2(point v1, point v2){
00042 double t = 0;
00043 int dx = v1.x - v2.x;
00044 int dy = v1.y - v2.y;
00045 int ax = abs(dx);
00046 int ay = abs(dy);
00047 if (dx == 0 && dy == 0) t = 0;
00048 else t = (double)dy /(double)(ax + ay);
00049 if (dx < 0) t = 2 - t;
00050 else if (dy < 0) t = 4 + t;
00051
00052 return t*90;
00053 }
00054
00055
00056
00057
00058
00059
00060
00061 inline double AngleRelativeToHorizontal(const point & pt1, const point& pt2) {
00062 double d1 = abs(pt2.x - pt1.x);
00063 double d2 = (pt2 - pt1).abs();
00064 if ((d2 == 0) || (d1/d2 < -1) || (d1/d2 > 1))
00065 return 0;
00066 else
00067 return acos(d1/d2);
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 template <class T> struct listed {
00081
00082 T* next;
00083
00084 listed(): next(0) {}
00085
00086 ~listed() {}
00087
00088 T* getNext() const {return next;}
00089
00090 void insert(T* i) {
00091 if (!i) return;
00092 T* tmp = next;
00093 next = i;
00094 i->setNext(tmp);
00095 }
00096
00097 void swapNext(T* toSwapWith) {
00098
00099 if (!(next && toSwapWith && toSwapWith->next)) return;
00100 T* tmp = this->next;
00101 T* tmp2 = toSwapWith->next->next;
00102
00103 this->next = toSwapWith->next;
00104 toSwapWith->next->next = tmp;
00105 toSwapWith->next = tmp2;
00106 }
00107
00108 };
00109
00110
00111
00112 template <class T> class slist {
00113
00114 private:
00115 unsigned int size;
00116 T* first, *last;
00117
00118 public:
00119
00120 class iterator {
00121
00122 private:
00123 T* elt;
00124 public:
00125
00126 iterator(T* l = 0) : elt(l) {}
00127
00128 T* operator++() {
00129 if (!elt) return 0;
00130 elt= elt->next;
00131 return elt;
00132 }
00133 T* operator++(int) {
00134 if (!elt) return 0;
00135 T* old = elt;
00136 elt = elt->next;
00137 return old;
00138 }
00139 T*operator+=(int n) {
00140 T* tmp = elt;
00141 int i;
00142 for (i = 0; i<n;++i)
00143 if (tmp) tmp = tmp->next;
00144 else return 0;
00145 elt = tmp;
00146 return elt;
00147 }
00148 T* operator = (T* e) {
00149 elt = e;
00150 return elt;
00151 }
00152 bool operator != (const T* e) const {
00153 return (elt != e);
00154 }
00155
00156 T* operator ->() const {return elt;}
00157 T* operator *() const {return elt;}
00158 bool end() {return !elt;}
00159 };
00160
00161 T* front() const {return first;}
00162 T* back() const {return last;}
00163 void setLast(T* l) {last = l;}
00164
00165 void cutFront() { first = last = 0;size = 0;}
00166
00167 slist() : size(0), first(0), last(0){}
00168
00169 void push_front(T* lp) {
00170 if (!lp) return;
00171 if (!last) last = lp;
00172
00173 lp->next = first;
00174 first = lp;
00175 ++size;
00176 }
00177
00178 void push_back(const T* lp) {
00179 if (!lp) return;
00180 if (!first) {first = last = lp;} else last->next = lp;
00181 last = lp;
00182 ++size;
00183 }
00184
00185 void push_back(slist<T>& lst) {
00186 if (last) {
00187 last->next = lst.front();
00188 last = lst.back();
00189 } else {
00190 first = lst.front();
00191 last = lst.back();
00192 }
00193 size+= lst.getSize();
00194 lst.cutFront();
00195 }
00196
00197 unsigned getSize() const {return size;}
00198 bool empty() {return size==0;}
00199
00200 void clear() {
00201 while (first) {
00202 T* tmp = first->next;
00203 delete first;
00204 first = tmp;
00205 }
00206 last = 0;
00207 size = 0;
00208 }
00209
00210 T* pop_front() {
00211 if (!first) return 0;
00212 T* tmp = first->next;
00213 delete first;
00214 first = tmp;
00215 if (size==1) last = first;
00216 --size;
00217 return first;
00218 }
00219
00220 void insert(T* pos, T* i) {
00221 if (!pos) return;
00222 T* tmp = pos->next;
00223
00224 if (!tmp) {
00225 pos->next = i;
00226 i->next = 0;
00227 last = i;
00228 } else {
00229 pos->next = i;
00230 i->next = tmp;
00231 }
00232 if (pos==last) last = i;
00233 ++size;
00234 }
00235
00236 void erase(T* e) {
00237
00238 if (e->next = last) last = e;
00239 T* n = e->next->next;
00240
00241 delete e->next;
00242 e->next = n;
00243 --size;
00244 }
00245
00246 };
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 struct figure : public listed<figure> {
00258
00259
00260 figure() : listed<figure>() {}
00261 virtual ~figure() {}
00262
00263 virtual unsigned short getId() = 0;
00264 virtual point toConsider() = 0;
00265 virtual double size() {return 0;}
00266 };
00267
00268 class edge : public figure {
00269 private:
00270 point pt;
00271 unsigned short id;
00272 public:
00273
00274 edge(point& p, unsigned short i) : figure(), pt(p) , id(i) {}
00275 edge(int& x, int& y, unsigned short i) : figure(), id(i) {
00276 pt.x = x; pt.y = y;
00277 }
00278
00279 point toConsider() {;return pt;}
00280 unsigned short getId() {return id;}
00281 };
00282
00283 struct LinePair : public figure {
00284 virtual point pt1() = 0;
00285 virtual point pt2() = 0;
00286 virtual direction getDirection() = 0;
00287 };
00288
00289 class horLinePair : public LinePair {
00290 point p1;
00291 int p2x;
00292 public:
00293
00294 horLinePair(point p1, int p2x) {
00295 this->p1 = p1;
00296 this->p2x = p2x;
00297 }
00298
00299 ~horLinePair() {}
00300
00301 horLinePair(point& p1, point& p2) {
00302 this->p1 = p1;
00303 this->p2x = p2.x;
00304 }
00305
00306 unsigned short getId() {return (unsigned short)p1.y;}
00307 point toConsider() {return point((p1.x+p2x)/2, p1.y);}
00308 point pt1() {return p1;}
00309 point pt2() {return point(p2x, p1.y);}
00310 double size() {return (double) (p2x - p1.x);}
00311 direction getDirection() {return direction(1,0);}
00312
00313
00314 };
00315
00316
00317
00318 struct extLinePair : public LinePair {
00319
00320 point p1, p2;
00321 unsigned short id;
00322
00323 extLinePair(point& p1, point& p2, unsigned short id = 0) {
00324 this->p1 = p1;
00325 this->p2 = p2;
00326 this->id = id;
00327 }
00328
00329 extLinePair() {
00330 this->p1 = point();
00331 this->p2 = point();
00332 this->id = 0;
00333 }
00334
00335 point pt1() {return p1;}
00336 point pt2() {return p2;}
00337 double size() {return (p2 - p1).abs();}
00338
00339 point toConsider() {return mil(p1, p2);}
00340
00341 unsigned short getId() {return id;}
00342 direction getDirection() {
00343 return direction((double)(p2.x - p1.x),(double)(p2.y - p1.y));
00344 }
00345
00346
00347 };
00348
00349
00350
00351 struct LinePair2 : public listed<LinePair2> {
00352
00353
00354 point p1, p2;
00355
00356 LinePair2(point& p1, point& p2) : listed<LinePair2>() {
00357 this->p1 = p1;
00358 this->p2 = p2;
00359 }
00360
00361
00362
00363
00364
00365
00366 bool operator <(const LinePair2& other){
00367 return p1.y < other.p1.y ||
00368 p1.y == other.p1.y && p1.x < other.p1.y ;
00369 }
00370
00371 virtual colorClass getColor() {return noColor;}
00372 virtual double getLength() {return (p2 - p1).abs();}
00373
00374 };
00375
00376
00377
00378
00379
00380
00381 class LinePair3 : public LinePair2 {
00382 private:
00383 double length;
00384 bool updated;
00385
00386 public:
00387
00388 void setP1(point& p) {
00389 updated = false;
00390 p1 = p;
00391 }
00392 void setP2(point& p) {
00393 updated = false;
00394 p2 = p;
00395 }
00396
00397
00398 LinePair3(point& p1, point& p2) : LinePair2(p1, p2), length(0), updated(false) {}
00399
00400 void updateLength() {
00401 length = (p2 - p1).abs();
00402 updated = true;
00403 }
00404 double getLength() {
00405 if (!updated) updateLength();
00406 return length;
00407 }
00408
00409 };
00410
00411
00412 struct coloredLinePair2 : public LinePair2 {
00413 private :
00414 colorClass color;
00415 public:
00416
00417
00418 coloredLinePair2(point& v1,point& v2, colorClass c = noColor) :
00419 LinePair2(v1, v2), color(c) {}
00420
00421 colorClass getColor() {return color;}
00422 };
00423
00424
00425
00426
00427
00428 inline double theta2(LinePair2* l1,LinePair2* l2) {
00429
00430 double angle1 = theta2(l1->p1,l1->p2);
00431 double angle = theta2(l2->p1, l2->p2) - angle1;
00432
00433 while (angle<0) angle+=360;
00434
00435 return angle;
00436
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 inline figure* getMin (figure * lp) {
00450
00451 figure * min = lp->getNext();
00452
00453 if (!min) return 0;
00454
00455 slist<figure>::iterator it = min;
00456
00457 double d_min = Geometry::distance(
00458 lp->toConsider(),
00459 it->toConsider());
00460
00461 unsigned short cur_id = min->getId();
00462
00463 while(++it && cur_id == it->getId()) {
00464
00465 double d = Geometry::distance(
00466 lp->toConsider(),
00467 it->toConsider());
00468
00469 if (d <d_min) {
00470 d_min = d;
00471 min = *it;
00472 }
00473 }
00474
00475 return min;
00476 }
00477
00478
00479
00480
00481
00482
00483
00484 inline void createLinearSegment(slist<figure>& lst) {
00485
00486 if (lst.getSize()<3)return;
00487 slist<figure>::iterator start = lst.front();
00488
00489 do {
00490 figure* min = getMin(*start);
00491 if (min != *start) start->swapNext(min);
00492 } while (++start && start->getNext());
00493
00494 lst.setLast(*start);
00495 }
00496
00497
00498
00499
00500
00501 inline Vector2<double> mil(LinePair2& lp) {
00502 return Vector2<double> ((lp.p1.x+lp.p2.x)/2, (lp.p1.y+lp.p2.y)/2);
00503 };
00504
00505
00506 inline Geometry::Line makeLine(LinePair2* lp) {
00507 Geometry::Line l;
00508
00509 l.base = Vector2<double> ((double)lp->p1.x, (double)lp->p1.y);
00510 l.direction = Vector2<double> ((double)lp->p2.x, (double)lp->p2.y) - l.base;
00511
00512 return l;
00513 };
00514
00515
00516 #endif
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536