![]() |
Tulip
4.6.0
Better Visualization Through Research
|
00001 /* 00002 * 00003 * This file is part of Tulip (www.tulip-software.org) 00004 * 00005 * Authors: David Auber and the Tulip development Team 00006 * from LaBRI, University of Bordeaux 00007 * 00008 * Tulip is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation, either version 3 00011 * of the License, or (at your option) any later version. 00012 * 00013 * Tulip is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 * See the GNU General Public License for more details. 00017 * 00018 */ 00019 ///@cond DOXYGEN_HIDDEN 00020 00021 //@TLPGEOLICENCE# 00022 #ifndef TLP_RECTANGLE_H 00023 #define TLP_RECTANGLE_H 00024 #include <tulip/Vector.h> 00025 #include <tulip/BoundingBox.h> 00026 00027 namespace tlp { 00028 00029 /** 00030 * @ingroup Structures 00031 * \brief class for rectangle 00032 * 00033 * Enables to both create and manipulate a 2D Axis Aligned Rectangle 00034 * 00035 * Author : <a href="www.tulip-software.org>Tulip team</a> 00036 */ 00037 template<typename Obj, typename OTYPE = double> 00038 struct Rectangle : public Array<Vector<Obj,2, OTYPE>,2> { 00039 /** 00040 * Create a new invalid rectangle 00041 */ 00042 Rectangle() { 00043 (*this)[0].fill(1); 00044 (*this)[1].fill(-1); 00045 } 00046 /** 00047 * Create a new rectangle with 00048 * (*this)[0] = min = (xmin, ymin); 00049 * (*this)[1] = max = (xmax, ymax); 00050 * \warning the rectangle must be valid (tested in debug mode) 00051 */ 00052 Rectangle(const Obj xmin, const Obj ymin, const Obj xmax, const Obj ymax) { 00053 (*this)[0][0] = xmin; 00054 (*this)[0][1] = ymin; 00055 (*this)[1][0] = xmax; 00056 (*this)[1][1] = ymax; 00057 assert(isValid()); 00058 } 00059 /** 00060 * Create a new Rectangle from a Bounding Box correct conversion from 3D -> 2D 00061 * \warning the rectangle must be valid (tested in debug mode) 00062 */ 00063 Rectangle(const tlp::BoundingBox &b) { 00064 (*this)[0][0] = b[0][0]; 00065 (*this)[0][1] = b[0][1]; 00066 (*this)[1][0] = b[1][0]; 00067 (*this)[1][1] = b[1][1]; 00068 assert(isValid()); 00069 } 00070 00071 /** 00072 * create a new Rectangle 00073 * \warning the rectangle must be valid (tested in debug mode) 00074 */ 00075 Rectangle(const Vector<Obj,2, OTYPE> &min, const Vector<Obj,2, OTYPE> &max) { 00076 (*this)[0] = min; 00077 (*this)[1] = max; 00078 assert(isValid()); 00079 } 00080 /** 00081 * @return true if r intersect "this". 00082 * \warning the rectangle must be valid (tested in debug mode) 00083 */ 00084 bool intersect(const Rectangle &r) const { 00085 assert(this->isValid()); 00086 assert(r.isValid()); 00087 00088 if ((*this)[0][0] > r[1][0]) return false; 00089 00090 if ((*this)[1][0] < r[0][0]) return false; 00091 00092 if ((*this)[0][1] > r[1][1]) return false; 00093 00094 if ((*this)[1][1] < r[0][1]) return false; 00095 00096 return true; 00097 } 00098 /** 00099 * @return the true if there is an intersection else false, the intersection parameter is used to stored the Rectangle pf intersection (if it exists). 00100 * \warning the rectangle must be valid (tested in debug mode) 00101 */ 00102 bool intersect(const Rectangle &r, Rectangle &intersection) const { 00103 assert(this->isValid()); 00104 assert(r.isValid()); 00105 00106 if (!this->intersect(r)) return false; 00107 00108 intersection[0][0] = std::max((*this)[0][0] , r[0][0]); 00109 intersection[1][0] = std::min((*this)[1][0] , r[1][0]); 00110 intersection[0][1] = std::max((*this)[0][1] , r[0][1]); 00111 intersection[1][1] = std::min((*this)[1][1] , r[1][1]); 00112 00113 return true; 00114 } 00115 /** 00116 * @return true if the Rectangle is well define [0] min corner, [1] max corner. 00117 */ 00118 bool isValid() const { 00119 return (*this)[0][0] <= (*this)[1][0] && (*this)[0][1] <= (*this)[1][1]; 00120 } 00121 /** 00122 * Return true if point is stricly inside the AARectangle 00123 * \warning the rectangle must be valid (tested in debug mode) 00124 */ 00125 bool isInside(const Vector<Obj, 2, OTYPE> &p) const { 00126 assert(isValid()); 00127 00128 if (p[0] > (*this)[1][0]) return false; 00129 00130 if (p[0] < (*this)[0][0]) return false; 00131 00132 if (p[1] > (*this)[1][1]) return false; 00133 00134 if (p[1] < (*this)[0][1]) return false; 00135 00136 return true; 00137 } 00138 /** 00139 * @return true if r is inside or equal to the AARectangle 00140 * \warning the rectangle must be valid (tested in debug mode) 00141 */ 00142 bool isInside(const Rectangle &r) const { 00143 assert(isValid()); 00144 assert(r.isValid()); 00145 00146 if ((*this)[0] == r[0] && (*this)[1] == r[1]) return true; 00147 00148 if (this->isInside(r[0]) && this->isInside(r[1])) return true; 00149 00150 return false; 00151 } 00152 00153 /** 00154 * Translate "this" by vector v 00155 * \warning the rectangle must be valid (tested in debug mode) 00156 */ 00157 void translate(const tlp::Vector<Obj,2, OTYPE> &v) { 00158 assert(isValid()); 00159 (*this)[0] += v; 00160 (*this)[1] += v; 00161 } 00162 /** 00163 * Return the width of the rectangle 00164 * \warning the rectangle must be valid (tested in debug mode) 00165 */ 00166 Obj width() const { 00167 assert(isValid()); 00168 return (*this)[1][0] - (*this)[0][0]; 00169 } 00170 /** 00171 * Return the height of the rectangle 00172 * \warning the rectangle must be valid (tested in debug mode) 00173 */ 00174 Obj height() const { 00175 assert(isValid()); 00176 return (*this)[1][1] - (*this)[0][1]; 00177 } 00178 /** 00179 * Return the surface of the rectangle 00180 * \warning the rectangle must be valid (tested in debug mode) 00181 */ 00182 Obj surface() const { 00183 assert(isValid()); 00184 return height() * width(); 00185 } 00186 /** 00187 * Return the aspect ratio of the reactangle 00188 * a value between [0..1] 00189 * \warning the rectangle must be valid (tested in debug mode) 00190 */ 00191 Obj aspectRatio() const { 00192 assert(isValid()); 00193 00194 if (std::max(height(), width()) < std::numeric_limits<Obj>::epsilon()) 00195 return 0.; 00196 00197 return std::min(height(), width()) / std::max(height(), width()); 00198 } 00199 /** 00200 * Return the center of a rectangle 00201 * \warning the rectangle must be valid (tested in debug mode) 00202 */ 00203 Vector<Obj, 2, OTYPE> center() const { 00204 assert(isValid()); 00205 return ((*this)[0] + (*this)[1]) / Obj(2); 00206 } 00207 00208 }; 00209 00210 typedef Rectangle<double, long double> Rectd; 00211 typedef Rectangle<float, double> Rectf; 00212 typedef Rectangle<int, double> Recti; 00213 typedef Rectangle<unsigned int, double> Rectui; 00214 00215 00216 00217 } 00218 #endif 00219 ///@endcond