|
|
|
|
|
#ifndef DLIB_BORDER_EnUMERATOR_H_ |
|
#define DLIB_BORDER_EnUMERATOR_H_ |
|
|
|
#include "border_enumerator_abstract.h" |
|
#include "rectangle.h" |
|
|
|
namespace dlib |
|
{ |
|
|
|
|
|
|
|
class border_enumerator |
|
{ |
|
public: |
|
border_enumerator( |
|
) |
|
{ |
|
reset(); |
|
} |
|
|
|
border_enumerator( |
|
const rectangle& rect_, |
|
unsigned long border_size |
|
) : |
|
rect(rect_), |
|
inner_rect(shrink_rect(rect_, border_size)) |
|
{ |
|
reset(); |
|
} |
|
|
|
border_enumerator( |
|
const rectangle& rect_, |
|
const rectangle& non_border_region |
|
) : |
|
rect(rect_), |
|
inner_rect(non_border_region.intersect(rect)) |
|
{ |
|
reset(); |
|
} |
|
|
|
void reset ( |
|
) |
|
{ |
|
|
|
|
|
bleft = rect.intersect(rectangle(std::numeric_limits<long>::min(), |
|
std::numeric_limits<long>::min(), |
|
inner_rect.left()-1, |
|
std::numeric_limits<long>::max())); |
|
|
|
bright = rect.intersect(rectangle(inner_rect.right()+1, |
|
std::numeric_limits<long>::min(), |
|
std::numeric_limits<long>::max(), |
|
std::numeric_limits<long>::max())); |
|
|
|
btop = rect.intersect(rectangle(inner_rect.left(), |
|
std::numeric_limits<long>::min(), |
|
inner_rect.right(), |
|
inner_rect.top()-1)); |
|
|
|
bbottom = rect.intersect(rectangle(inner_rect.left(), |
|
inner_rect.bottom()+1, |
|
inner_rect.right(), |
|
std::numeric_limits<long>::max())); |
|
|
|
p = bleft.tl_corner(); |
|
p.x() -= 1; |
|
|
|
mode = atleft; |
|
} |
|
|
|
bool at_start ( |
|
) const |
|
{ |
|
point temp = bleft.tl_corner(); |
|
temp.x() -=1; |
|
return temp == p; |
|
} |
|
|
|
bool current_element_valid( |
|
) const |
|
{ |
|
return rect.contains(p); |
|
} |
|
|
|
bool move_next() |
|
{ |
|
if (mode == atleft) |
|
{ |
|
if (advance_point(bleft, p)) |
|
return true; |
|
|
|
mode = attop; |
|
p = btop.tl_corner(); |
|
p.x() -= 1; |
|
} |
|
if (mode == attop) |
|
{ |
|
if (advance_point(btop, p)) |
|
return true; |
|
|
|
mode = atright; |
|
p = bright.tl_corner(); |
|
p.x() -= 1; |
|
} |
|
if (mode == atright) |
|
{ |
|
if (advance_point(bright, p)) |
|
return true; |
|
|
|
mode = atbottom; |
|
p = bbottom.tl_corner(); |
|
p.x() -= 1; |
|
} |
|
|
|
if (advance_point(bbottom, p)) |
|
return true; |
|
|
|
|
|
p = rect.br_corner(); |
|
p.x() += 1; |
|
|
|
return false; |
|
} |
|
|
|
size_t size ( |
|
) const |
|
{ |
|
return rect.area() - inner_rect.area(); |
|
} |
|
|
|
const point& element ( |
|
) const |
|
{ |
|
|
|
DLIB_ASSERT(current_element_valid(), |
|
"\t point border_enumerator::element()" |
|
<< "\n\t This function can't be called unless the element is valid." |
|
<< "\n\t this: " << this |
|
); |
|
|
|
return p; |
|
} |
|
|
|
private: |
|
|
|
bool advance_point ( |
|
const rectangle& r, |
|
point& p |
|
) const |
|
{ |
|
p.x() += 1; |
|
if (p.x() > r.right()) |
|
{ |
|
p.x() = r.left(); |
|
p.y() += 1; |
|
} |
|
|
|
return r.contains(p); |
|
} |
|
|
|
point p; |
|
rectangle rect; |
|
rectangle inner_rect; |
|
|
|
enum emode |
|
{ |
|
atleft, |
|
atright, |
|
atbottom, |
|
attop |
|
}; |
|
|
|
emode mode; |
|
|
|
rectangle btop, bleft, bright, bbottom; |
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
#endif |
|
|
|
|