#ifndef SEEN_NR_RECT_L_H #define SEEN_NR_RECT_L_H #include struct NRRectL { NR::ICoord x0, y0, x1, y1; }; #include #include namespace NR { class IRect { public: IRect(const NRRectL& r) : _min(r.x0, r.y0), _max(r.x1, r.y1) {} IRect(const IRect& r) : _min(r._min), _max(r._max) {} IRect(const IPoint &p0, const IPoint &p1); /** as not all Rects are representable by IRects this gives the smallest IRect that contains * r. */ IRect(const Rect& r); operator Rect() { return Rect(Point(_min), Point(_max)); } const IPoint &min() const { return _min; } const IPoint &max() const { return _max; } /** returns a vector from min to max. */ IPoint dimensions() const; /** does this rectangle have zero area? */ bool isEmpty() const { return isEmpty() && isEmpty(); } bool intersects(const IRect &r) const { return intersects(r) && intersects(r); } bool contains(const IRect &r) const { return contains(r) && contains(r); } bool contains(const IPoint &p) const { return contains(p) && contains(p); } ICoord maxExtent() const { return MAX(extent(), extent()); } ICoord extent(Dim2 axis) const { switch (axis) { case X: return extent(); case Y: return extent(); }; } ICoord extent(unsigned i) const throw(std::out_of_range) { switch (i) { case 0: return extent(); case 1: return extent(); default: throw std::out_of_range("Dimension out of range"); }; } /** Translates the rectangle by p. */ void offset(IPoint p); /** Makes this rectangle large enough to include the point p. */ void expandTo(IPoint p); /** Makes this rectangle large enough to include the rectangle r. */ void expandTo(const IRect &r); /** Returns the set of points shared by both rectangles. */ static Maybe intersection(const IRect &a, const IRect &b); /** Returns the smallest rectangle that encloses both rectangles. */ static IRect union_bounds(const IRect &a, const IRect &b); private: IRect() {} template ICoord extent() const { return _max[axis] - _min[axis]; } template bool isEmpty() const { return !( _min[axis] < _max[axis] ); } template bool intersects(const IRect &r) const { return _max[axis] >= r._min[axis] && _min[axis] <= r._max[axis]; } template bool contains(const IRect &r) const { return contains(r._min) && contains(r._max); } template bool contains(const IPoint &p) const { return p[axis] >= _min[axis] && p[axis] <= _max[axis]; } IPoint _min, _max; }; } // namespace NR #endif /* !SEEN_NR_RECT_L_H */ /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :