Tulip  4.6.0
Better Visualization Through Research
library/tulip-core/include/tulip/Rectangle.h
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
 All Classes Files Functions Variables Enumerations Enumerator Properties