Tulip  4.3.0
Better Visualization Through Research
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Groups Pages
Rectangle.h
1 /*
2  *
3  * This file is part of Tulip (www.tulip-software.org)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux 1 and Inria Bordeaux - Sud Ouest
7  *
8  * Tulip is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation, either version 3
11  * of the License, or (at your option) any later version.
12  *
13  * Tulip is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  *
18  */
19 ///@cond DOXYGEN_HIDDEN
20 
21 //@TLPGEOLICENCE#
22 #ifndef TLP_RECTANGLE_H
23 #define TLP_RECTANGLE_H
24 #include <tulip/Vector.h>
25 #include <tulip/BoundingBox.h>
26 
27 namespace tlp {
28 
29 /**
30  * @ingroup Structures
31  * \brief class for rectangle
32  *
33  * Enables to both create and manipulate a 2D Axis Aligned Rectangle
34  *
35  * Author : <a href="www.tulip-software.org>Tulip team</a>
36  */
37 template<typename Obj, typename OTYPE = double>
38 struct Rectangle : public Array<Vector<Obj,2, OTYPE>,2> {
39  /**
40  * Create a new invalid rectangle
41  */
42  Rectangle() {
43  (*this)[0].fill(1);
44  (*this)[1].fill(-1);
45  }
46  /**
47  * Create a new rectangle with
48  * (*this)[0] = min = (xmin, ymin);
49  * (*this)[1] = max = (xmax, ymax);
50  * \warning the rectangle must be valid (tested in debug mode)
51  */
52  Rectangle(const Obj xmin, const Obj ymin, const Obj xmax, const Obj ymax) {
53  (*this)[0][0] = xmin;
54  (*this)[0][1] = ymin;
55  (*this)[1][0] = xmax;
56  (*this)[1][1] = ymax;
57  assert(isValid());
58  }
59  /**
60  * Create a new Rectangle from a Bounding Box correct conversion from 3D -> 2D
61  * \warning the rectangle must be valid (tested in debug mode)
62  */
63  Rectangle(const tlp::BoundingBox &b) {
64  (*this)[0][0] = b[0][0];
65  (*this)[0][1] = b[0][1];
66  (*this)[1][0] = b[1][0];
67  (*this)[1][1] = b[1][1];
68  assert(isValid());
69  }
70 
71  /**
72  * create a new Rectangle
73  * \warning the rectangle must be valid (tested in debug mode)
74  */
75  Rectangle(const Vector<Obj,2, OTYPE> &min, const Vector<Obj,2, OTYPE> &max) {
76  (*this)[0] = min;
77  (*this)[1] = max;
78  assert(isValid());
79  }
80  /**
81  * @return true if r intersect "this".
82  * \warning the rectangle must be valid (tested in debug mode)
83  */
84  bool intersect(const Rectangle &r) const {
85  assert(this->isValid());
86  assert(r.isValid());
87 
88  if ((*this)[0][0] > r[1][0]) return false;
89 
90  if ((*this)[1][0] < r[0][0]) return false;
91 
92  if ((*this)[0][1] > r[1][1]) return false;
93 
94  if ((*this)[1][1] < r[0][1]) return false;
95 
96  return true;
97  }
98  /**
99  * @return the true if there is an intersection else false, the intersection parameter is used to stored the Rectangle pf intersection (if it exists).
100  * \warning the rectangle must be valid (tested in debug mode)
101  */
102  bool intersect(const Rectangle &r, Rectangle &intersection) const {
103  assert(this->isValid());
104  assert(r.isValid());
105 
106  if (!this->intersect(r)) return false;
107 
108  intersection[0][0] = std::max((*this)[0][0] , r[0][0]);
109  intersection[1][0] = std::min((*this)[1][0] , r[1][0]);
110  intersection[0][1] = std::max((*this)[0][1] , r[0][1]);
111  intersection[1][1] = std::min((*this)[1][1] , r[1][1]);
112 
113  return true;
114  }
115  /**
116  * @return true if the Rectangle is well define [0] min corner, [1] max corner.
117  */
118  bool isValid() const {
119  return (*this)[0][0] <= (*this)[1][0] && (*this)[0][1] <= (*this)[1][1];
120  }
121  /**
122  * Return true if point is stricly inside the AARectangle
123  * \warning the rectangle must be valid (tested in debug mode)
124  */
125  bool isInside(const Vector<Obj, 2, OTYPE> &p) const {
126  assert(isValid());
127 
128  if (p[0] > (*this)[1][0]) return false;
129 
130  if (p[0] < (*this)[0][0]) return false;
131 
132  if (p[1] > (*this)[1][1]) return false;
133 
134  if (p[1] < (*this)[0][1]) return false;
135 
136  return true;
137  }
138  /**
139  * @return true if r is inside or equal to the AARectangle
140  * \warning the rectangle must be valid (tested in debug mode)
141  */
142  bool isInside(const Rectangle &r) const {
143  assert(isValid());
144  assert(r.isValid());
145 
146  if ((*this)[0] == r[0] && (*this)[1] == r[1]) return true;
147 
148  if (this->isInside(r[0]) && this->isInside(r[1])) return true;
149 
150  return false;
151  }
152 
153  /**
154  * Translate "this" by vector v
155  * \warning the rectangle must be valid (tested in debug mode)
156  */
157  void translate(const tlp::Vector<Obj,2, OTYPE> &v) {
158  assert(isValid());
159  (*this)[0] += v;
160  (*this)[1] += v;
161  }
162  /**
163  * Return the width of the rectangle
164  * \warning the rectangle must be valid (tested in debug mode)
165  */
166  Obj width() const {
167  assert(isValid());
168  return (*this)[1][0] - (*this)[0][0];
169  }
170  /**
171  * Return the height of the rectangle
172  * \warning the rectangle must be valid (tested in debug mode)
173  */
174  Obj height() const {
175  assert(isValid());
176  return (*this)[1][1] - (*this)[0][1];
177  }
178  /**
179  * Return the surface of the rectangle
180  * \warning the rectangle must be valid (tested in debug mode)
181  */
182  Obj surface() const {
183  assert(isValid());
184  return height() * width();
185  }
186  /**
187  * Return the aspect ratio of the reactangle
188  * a value between [0..1]
189  * \warning the rectangle must be valid (tested in debug mode)
190  */
191  Obj aspectRatio() const {
192  assert(isValid());
193 
194  if (std::max(height(), width()) < std::numeric_limits<Obj>::epsilon())
195  return 0.;
196 
197  return std::min(height(), width()) / std::max(height(), width());
198  }
199  /**
200  * Return the center of a rectangle
201  * \warning the rectangle must be valid (tested in debug mode)
202  */
203  Vector<Obj, 2, OTYPE> center() const {
204  assert(isValid());
205  return ((*this)[0] + (*this)[1]) / Obj(2);
206  }
207 
208 };
209 
210 typedef Rectangle<double, long double> Rectd;
211 typedef Rectangle<float, double> Rectf;
212 typedef Rectangle<int, double> Recti;
213 typedef Rectangle<unsigned int, double> Rectui;
214 
215 
216 
217 }
218 #endif
219 ///@endcond