ccstruct/rect.h

Go to the documentation of this file.
00001 
00020 #ifndef           RECT_H
00021 #define           RECT_H
00022 
00023 #include          <math.h>
00024 #include          "points.h"
00025 #include          "ndminx.h"
00026 #include          "grphics.h"
00027 #include          "tprintf.h"
00028 
00033 class DLLSYM BOX
00034 {
00035   public:
00036     BOX ():                      //empty constructor
00037     bot_left (MAX_INT16, MAX_INT16), top_right (-MAX_INT16, -MAX_INT16) {
00038     }                            //null box
00039 
00040     BOX(                    //constructor
00041         const ICOORD pt1,   //one corner
00042         const ICOORD pt2);  //the other corner
00043     BOX(  //box around FCOORD
00044         const FCOORD pt);
00045 
00046     BOOL8 null_box() const {  //Is box null
00047       return ((left () > right ()) || (top () < bottom ()));
00048     }
00049 
00050     INT16 top() const {  // coord of top
00051       return top_right.y ();
00052     }
00053 
00054     INT16 bottom() const {  // coord of bottom
00055       return bot_left.y ();
00056     }
00057 
00058     INT16 left() const {  // coord of left
00059       return bot_left.x ();
00060     }
00061 
00062     INT16 right() const {  // coord of right
00063       return top_right.x ();
00064     }
00065 
00066                                  //access function
00067     const ICOORD &botleft() const {
00068       return bot_left;
00069     }
00070 
00071     ICOORD botright() const {  // ~ access function
00072       return ICOORD (top_right.x (), bot_left.y ());
00073     }
00074 
00075     ICOORD topleft() const {  // ~ access function
00076       return ICOORD (bot_left.x (), top_right.y ());
00077     }
00078 
00079                                  //access function
00080     const ICOORD &topright() const {
00081       return top_right;
00082     }
00083 
00084     INT16 height() const {  //how high is it?
00085       if (!null_box ())
00086         return top_right.y () - bot_left.y ();
00087       else
00088         return 0;
00089     }
00090 
00091     INT16 width() const {  //how high is it?
00092       if (!null_box ())
00093         return top_right.x () - bot_left.x ();
00094       else
00095         return 0;
00096     }
00097 
00098     INT32 area() const {  //what is the area?
00099       if (!null_box ())
00100         return width () * height ();
00101       else
00102         return 0;
00103     }
00104 
00105     void move_bottom_edge(                  // move one edge
00106                           const INT16 y) {  // by +/- y
00107       bot_left += ICOORD (0, y);
00108     }
00109 
00110     void move_left_edge(                  // move one edge
00111                         const INT16 x) {  // by +/- x
00112       bot_left += ICOORD (x, 0);
00113     }
00114 
00115     void move_right_edge(                  // move one edge
00116                          const INT16 x) {  // by +/- x
00117       top_right += ICOORD (x, 0);
00118     }
00119 
00120     void move_top_edge(                  // move one edge
00121                        const INT16 y) {  // by +/- y
00122       top_right += ICOORD (0, y);
00123     }
00124 
00125     void move(                     // move box
00126               const ICOORD vec) {  // by vector
00127       bot_left += vec;
00128       top_right += vec;
00129     }
00130 
00131     void move(                     // move box
00132               const FCOORD vec) {  // by float vector
00133       bot_left.set_x ((INT16) floor (bot_left.x () + vec.x ()));
00134       //round left
00135       bot_left.set_y ((INT16) floor (bot_left.y () + vec.y ()));
00136       //round down
00137 
00138       top_right.set_x ((INT16) ceil (top_right.x () + vec.x ()));
00139       //round right
00140       top_right.set_y ((INT16) ceil (top_right.y () + vec.y ()));
00141       //round up
00142     }
00143 
00144     void scale(                  // scale box
00145                const float f) {  // by multiplier
00146                                  //round left
00147       bot_left.set_x ((INT16) floor (bot_left.x () * f));
00148                                  //round down
00149       bot_left.set_y ((INT16) floor (bot_left.y () * f));
00150 
00151       top_right.set_x ((INT16) ceil (top_right.x () * f));
00152       //round right
00153       top_right.set_y ((INT16) ceil (top_right.y () * f));
00154       //round up
00155     }
00156     void scale(                     // scale box
00157                const FCOORD vec) {  // by float vector
00158       bot_left.set_x ((INT16) floor (bot_left.x () * vec.x ()));
00159       bot_left.set_y ((INT16) floor (bot_left.y () * vec.y ()));
00160       top_right.set_x ((INT16) ceil (top_right.x () * vec.x ()));
00161       top_right.set_y ((INT16) ceil (top_right.y () * vec.y ()));
00162     }
00163 
00164     void rotate(                     //rotate coords
00165                 const FCOORD vec) {  //by vector
00166       bot_left.rotate (vec);
00167       top_right.rotate (vec);
00168       *this = BOX (bot_left, top_right);
00169     }
00170 
00171     BOOL8 contains(  //is pt inside box
00172                    const FCOORD pt) const;
00173 
00174     BOOL8 contains(  //is box inside box
00175                    const BOX &box) const;
00176 
00177     BOOL8 overlap(  //do boxes overlap
00178                   const BOX &box) const;
00179 
00180     BOOL8 major_overlap(  // Do boxes overlap more than half.
00181                         const BOX &box) const;
00182 
00183     BOX intersection(  //shared area box
00184                      const BOX &box) const;
00185 
00186     BOX bounding_union(  //box enclosing both
00187                        const BOX &box) const;
00188 
00189     void print() {  //print
00190       tprintf ("Bounding box=(%d,%d)->(%d,%d)\n",
00191         left (), bottom (), right (), top ());
00192     }
00193 
00194 #ifndef GRAPHICS_DISABLED
00195     void plot(                    //use current settings
00196               WINDOW fd) const {  //where to paint
00197       rectangle (fd, bot_left.x (), bot_left.y (), top_right.x (),
00198         top_right.y ());
00199     }
00200 
00201     void plot(                              //paint box
00202               WINDOW fd,                    //where to paint
00203               INT16 style,                  //display style
00204               INT16 edged,                  //show border?
00205               COLOUR fill_colour,           //colour for inside
00206               COLOUR border_colour) const;  //colour for border
00207 #endif
00208 
00209     friend DLLSYM BOX & operator+= (BOX &, const BOX &);
00210     //in place union
00211     friend DLLSYM BOX & operator-= (BOX &, const BOX &);
00212     //in place intrsection
00213 
00214     void serialise_asc(  //convert to ascii
00215                        FILE *f);
00216     void de_serialise_asc(  //convert from ascii
00217                           FILE *f);
00218 
00219   private:
00220     ICOORD bot_left;             //bottom left corner
00221     ICOORD top_right;            //top right corner
00222 };
00223 
00227 inline BOX::BOX(                 //construtor
00228                 const FCOORD pt  //floating centre
00229                ) {
00230   bot_left = ICOORD ((INT16) floor (pt.x ()), (INT16) floor (pt.y ()));
00231   top_right = ICOORD ((INT16) ceil (pt.x ()), (INT16) ceil (pt.y ()));
00232 }
00233 
00234 
00238 inline BOOL8 BOX::contains(const FCOORD pt) const { 
00239   return ((pt.x () >= bot_left.x ()) &&
00240     (pt.x () <= top_right.x ()) &&
00241     (pt.y () >= bot_left.y ()) && (pt.y () <= top_right.y ()));
00242 }
00243 
00244 
00248 inline BOOL8 BOX::contains(const BOX &box) const { 
00249   return (contains (box.bot_left) && contains (box.top_right));
00250 }
00251 
00252 
00256 inline BOOL8 BOX::overlap(  //do boxes overlap
00257                           const BOX &box) const {
00258   return ((box.bot_left.x () <= top_right.x ()) &&
00259     (box.top_right.x () >= bot_left.x ()) &&
00260     (box.bot_left.y () <= top_right.y ()) &&
00261     (box.top_right.y () >= bot_left.y ()));
00262 }
00263 
00264 /**********************************************************************
00265  * BOX::major_overlap()  Do two boxes overlap by at least half of the smallest?
00266  *
00267  **********************************************************************/
00268 
00269 inline BOOL8 BOX::major_overlap(  // Do boxes overlap more that half.
00270                                 const BOX &box) const {
00271   int overlap = MIN(box.top_right.x(), top_right.x());
00272   overlap -= MAX(box.bot_left.x(), bot_left.x());
00273   overlap += overlap;
00274   if (overlap < MIN(box.width(), width()))
00275     return false;
00276   overlap = MIN(box.top_right.y(), top_right.y());
00277   overlap -= MAX(box.bot_left.y(), bot_left.y());
00278   overlap += overlap;
00279   if (overlap < MIN(box.height(), height()))
00280     return false;
00281   return true;
00282 }
00283 #endif

Generated on Wed Feb 28 19:49:08 2007 for Tesseract by  doxygen 1.5.1