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 ():
00037 bot_left (MAX_INT16, MAX_INT16), top_right (-MAX_INT16, -MAX_INT16) {
00038 }
00039
00040 BOX(
00041 const ICOORD pt1,
00042 const ICOORD pt2);
00043 BOX(
00044 const FCOORD pt);
00045
00046 BOOL8 null_box() const {
00047 return ((left () > right ()) || (top () < bottom ()));
00048 }
00049
00050 INT16 top() const {
00051 return top_right.y ();
00052 }
00053
00054 INT16 bottom() const {
00055 return bot_left.y ();
00056 }
00057
00058 INT16 left() const {
00059 return bot_left.x ();
00060 }
00061
00062 INT16 right() const {
00063 return top_right.x ();
00064 }
00065
00066
00067 const ICOORD &botleft() const {
00068 return bot_left;
00069 }
00070
00071 ICOORD botright() const {
00072 return ICOORD (top_right.x (), bot_left.y ());
00073 }
00074
00075 ICOORD topleft() const {
00076 return ICOORD (bot_left.x (), top_right.y ());
00077 }
00078
00079
00080 const ICOORD &topright() const {
00081 return top_right;
00082 }
00083
00084 INT16 height() const {
00085 if (!null_box ())
00086 return top_right.y () - bot_left.y ();
00087 else
00088 return 0;
00089 }
00090
00091 INT16 width() const {
00092 if (!null_box ())
00093 return top_right.x () - bot_left.x ();
00094 else
00095 return 0;
00096 }
00097
00098 INT32 area() const {
00099 if (!null_box ())
00100 return width () * height ();
00101 else
00102 return 0;
00103 }
00104
00105 void move_bottom_edge(
00106 const INT16 y) {
00107 bot_left += ICOORD (0, y);
00108 }
00109
00110 void move_left_edge(
00111 const INT16 x) {
00112 bot_left += ICOORD (x, 0);
00113 }
00114
00115 void move_right_edge(
00116 const INT16 x) {
00117 top_right += ICOORD (x, 0);
00118 }
00119
00120 void move_top_edge(
00121 const INT16 y) {
00122 top_right += ICOORD (0, y);
00123 }
00124
00125 void move(
00126 const ICOORD vec) {
00127 bot_left += vec;
00128 top_right += vec;
00129 }
00130
00131 void move(
00132 const FCOORD vec) {
00133 bot_left.set_x ((INT16) floor (bot_left.x () + vec.x ()));
00134
00135 bot_left.set_y ((INT16) floor (bot_left.y () + vec.y ()));
00136
00137
00138 top_right.set_x ((INT16) ceil (top_right.x () + vec.x ()));
00139
00140 top_right.set_y ((INT16) ceil (top_right.y () + vec.y ()));
00141
00142 }
00143
00144 void scale(
00145 const float f) {
00146
00147 bot_left.set_x ((INT16) floor (bot_left.x () * f));
00148
00149 bot_left.set_y ((INT16) floor (bot_left.y () * f));
00150
00151 top_right.set_x ((INT16) ceil (top_right.x () * f));
00152
00153 top_right.set_y ((INT16) ceil (top_right.y () * f));
00154
00155 }
00156 void scale(
00157 const FCOORD vec) {
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(
00165 const FCOORD vec) {
00166 bot_left.rotate (vec);
00167 top_right.rotate (vec);
00168 *this = BOX (bot_left, top_right);
00169 }
00170
00171 BOOL8 contains(
00172 const FCOORD pt) const;
00173
00174 BOOL8 contains(
00175 const BOX &box) const;
00176
00177 BOOL8 overlap(
00178 const BOX &box) const;
00179
00180 BOOL8 major_overlap(
00181 const BOX &box) const;
00182
00183 BOX intersection(
00184 const BOX &box) const;
00185
00186 BOX bounding_union(
00187 const BOX &box) const;
00188
00189 void print() {
00190 tprintf ("Bounding box=(%d,%d)->(%d,%d)\n",
00191 left (), bottom (), right (), top ());
00192 }
00193
00194 #ifndef GRAPHICS_DISABLED
00195 void plot(
00196 WINDOW fd) const {
00197 rectangle (fd, bot_left.x (), bot_left.y (), top_right.x (),
00198 top_right.y ());
00199 }
00200
00201 void plot(
00202 WINDOW fd,
00203 INT16 style,
00204 INT16 edged,
00205 COLOUR fill_colour,
00206 COLOUR border_colour) const;
00207 #endif
00208
00209 friend DLLSYM BOX & operator+= (BOX &, const BOX &);
00210
00211 friend DLLSYM BOX & operator-= (BOX &, const BOX &);
00212
00213
00214 void serialise_asc(
00215 FILE *f);
00216 void de_serialise_asc(
00217 FILE *f);
00218
00219 private:
00220 ICOORD bot_left;
00221 ICOORD top_right;
00222 };
00223
00227 inline BOX::BOX(
00228 const FCOORD pt
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(
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
00266
00267
00268
00269 inline BOOL8 BOX::major_overlap(
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