Commit ea897b9e authored by Davis King's avatar Davis King

Made the border_enumerator a little more flexible. Now the border

doesn't need to be the same size on all sides of a rectangle.
parent 7bd18841
......@@ -17,6 +17,7 @@ namespace dlib
border_enumerator(
)
{
reset();
}
border_enumerator(
......@@ -29,17 +30,51 @@ namespace dlib
reset();
}
border_enumerator(
const rectangle& rect_,
const rectangle& non_border_region
) :
rect(rect_),
inner_rect(non_border_region.intersect(rect))
{
reset();
}
void reset (
)
{
p = rect.tl_corner();
// make the four rectangles that surround inner_rect and intersect them
// with rect.
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 = rect.tl_corner();
point temp = bleft.tl_corner();
temp.x() -=1;
return temp == p;
}
......@@ -47,23 +82,47 @@ namespace dlib
bool current_element_valid(
) const
{
return rect.contains(p) && !inner_rect.contains(p);
return rect.contains(p);
}
bool move_next()
{
p.x() += 1;
if (p.x() > rect.right())
if (mode == atleft)
{
p.y() += 1;
p.x() = rect.left();
if (advance_point(bleft, p))
return true;
mode = attop;
p = btop.tl_corner();
p.x() -= 1;
}
else if (inner_rect.contains(p))
if (mode == attop)
{
p.x() = inner_rect.right()+1;
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;
return current_element_valid();
// put p outside rect since there are no more points to enumerate
p = rect.br_corner();
p.x() += 1;
return false;
}
unsigned long size (
......@@ -87,9 +146,36 @@ namespace dlib
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; // the non-border regions of rect
enum emode
{
atleft,
atright,
atbottom,
attop
};
emode mode;
rectangle btop, bleft, bright, bbottom;
};
// ----------------------------------------------------------------------------------------
......
......@@ -49,6 +49,19 @@ namespace dlib
(i.e. the number of points in the border area of rect)
!*/
border_enumerator(
const rectangle& rect,
const rectangle& non_border_region
);
/*!
ensures
- This object will enumerate over all points which are in rect but
not in non_border_region.
- current_element_valid() == false
- at_start() == true
- size() == rect.area() - rect.intersect(non_border_region).area()
!*/
bool at_start (
) const;
/*!
......
......@@ -526,6 +526,93 @@ namespace
}
}
{
matrix<bool,4,5> hits, truth;
const rectangle rect = rectangle(1,1,4,3);
border_enumerator be(rect, rectangle(2,2, 3, 3));
DLIB_TEST(be.size() == 8);
hits = false;
while (be.move_next())
{
DLIB_TEST(rect.contains(be.element()));
hits(be.element().y(), be.element().x()) = true;
}
DLIB_TEST(be.current_element_valid() == false);
DLIB_TEST(be.size() == 8);
truth = false;
truth(1,1) = truth(1,2) = truth(1,3) = truth(1,4) = truth(2,1) =
truth(3,1) = truth(2,4) = truth(3,4) = true;
DLIB_TEST_MSG(truth == hits, truth << endl << hits);
be = border_enumerator(rect, rectangle(0,0, 9, 9));
DLIB_TEST(be.size() == 0);
hits = false;
while (be.move_next())
{
DLIB_TEST(rect.contains(be.element()));
hits(be.element().y(), be.element().x()) = true;
}
DLIB_TEST(be.current_element_valid() == false);
DLIB_TEST(be.size() == 0);
truth = false;
DLIB_TEST(truth == hits);
be = border_enumerator(rect, rectangle(0,0, 3, 9));
DLIB_TEST(be.size() == 3);
hits = false;
while (be.move_next())
{
DLIB_TEST(rect.contains(be.element()));
hits(be.element().y(), be.element().x()) = true;
}
DLIB_TEST(be.current_element_valid() == false);
DLIB_TEST(be.size() == 3);
truth = false;
truth(1,4) = truth(2,4) = truth(3,4) = true;
DLIB_TEST(truth == hits);
be = border_enumerator(rect, rectangle(2,1, 4, 3));
DLIB_TEST(be.size() == 3);
hits = false;
while (be.move_next())
{
DLIB_TEST(rect.contains(be.element()));
hits(be.element().y(), be.element().x()) = true;
}
DLIB_TEST(be.current_element_valid() == false);
DLIB_TEST(be.size() == 3);
truth = false;
truth(1,1) = truth(2,1) = truth(3,1) = true;
DLIB_TEST(truth == hits);
be = border_enumerator(rect, rectangle(1,1, 5, 2));
DLIB_TEST(be.size() == 4);
hits = false;
while (be.move_next())
{
DLIB_TEST(rect.contains(be.element()));
hits(be.element().y(), be.element().x()) = true;
}
DLIB_TEST(be.current_element_valid() == false);
DLIB_TEST(be.size() == 4);
truth = false;
truth(3,1) = truth(3,2) = truth(3,3) = truth(3,4) = true;
DLIB_TEST(truth == hits);
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment