Tulip  5.3.0
Large graphs analysis and drawing
Rectangle.h
1 /*
2  *
3  * This file is part of Tulip (http://tulip.labri.fr)
4  *
5  * Authors: David Auber and the Tulip development Team
6  * from LaBRI, University of Bordeaux
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="http://tulip.labri.fr>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])
89  return false;
90 
91  if ((*this)[1][0] < r[0][0])
92  return false;
93 
94  if ((*this)[0][1] > r[1][1])
95  return false;
96 
97  if ((*this)[1][1] < r[0][1])
98  return false;
99 
100  return true;
101  }
102  /**
103  * @return the true if there is an intersection else false, the intersection parameter is used
104  * to stored the Rectangle pf intersection (if it exists).
105  * \warning the rectangle must be valid (tested in debug mode)
106  */
107  bool intersect(const Rectangle &r, Rectangle &intersection) const {
108  assert(this->isValid());
109  assert(r.isValid());
110 
111  if (!this->intersect(r))
112  return false;
113 
114  intersection[0][0] = std::max((*this)[0][0], r[0][0]);
115  intersection[1][0] = std::min((*this)[1][0], r[1][0]);
116  intersection[0][1] = std::max((*this)[0][1], r[0][1]);
117  intersection[1][1] = std::min((*this)[1][1], r[1][1]);
118 
119  return true;
120  }
121  /**
122  * @return true if the Rectangle is well define [0] min corner, [1] max corner.
123  */
124  bool isValid() const {
125  return (*this)[0][0] <= (*this)[1][0] && (*this)[0][1] <= (*this)[1][1];
126  }
127  /**
128  * Return true if point is stricly inside the AARectangle
129  * \warning the rectangle must be valid (tested in debug mode)
130  */
131  bool isInside(const Vector<Obj, 2, OTYPE> &p) const {
132  assert(isValid());
133 
134  if (p[0] > (*this)[1][0])
135  return false;
136 
137  if (p[0] < (*this)[0][0])
138  return false;
139 
140  if (p[1] > (*this)[1][1])
141  return false;
142 
143  if (p[1] < (*this)[0][1])
144  return false;
145 
146  return true;
147  }
148  /**
149  * @return true if r is inside or equal to the AARectangle
150  * \warning the rectangle must be valid (tested in debug mode)
151  */
152  bool isInside(const Rectangle &r) const {
153  assert(isValid());
154  assert(r.isValid());
155 
156  if ((*this)[0] == r[0] && (*this)[1] == r[1])
157  return true;
158 
159  if (this->isInside(r[0]) && this->isInside(r[1]))
160  return true;
161 
162  return false;
163  }
164 
165  /**
166  * Translate "this" by vector v
167  * \warning the rectangle must be valid (tested in debug mode)
168  */
169  void translate(const tlp::Vector<Obj, 2, OTYPE> &v) {
170  assert(isValid());
171  (*this)[0] += v;
172  (*this)[1] += v;
173  }
174  /**
175  * Return the width of the rectangle
176  * \warning the rectangle must be valid (tested in debug mode)
177  */
178  Obj width() const {
179  assert(isValid());
180  return (*this)[1][0] - (*this)[0][0];
181  }
182  /**
183  * Return the height of the rectangle
184  * \warning the rectangle must be valid (tested in debug mode)
185  */
186  Obj height() const {
187  assert(isValid());
188  return (*this)[1][1] - (*this)[0][1];
189  }
190  /**
191  * Return the surface of the rectangle
192  * \warning the rectangle must be valid (tested in debug mode)
193  */
194  Obj surface() const {
195  assert(isValid());
196  return height() * width();
197  }
198  /**
199  * Return the aspect ratio of the reactangle
200  * a value between [0..1]
201  * \warning the rectangle must be valid (tested in debug mode)
202  */
203  Obj aspectRatio() const {
204  assert(isValid());
205 
206  if (std::max(height(), width()) < std::numeric_limits<Obj>::epsilon())
207  return 0.;
208 
209  return std::min(height(), width()) / std::max(height(), width());
210  }
211  /**
212  * Return the center of a rectangle
213  * \warning the rectangle must be valid (tested in debug mode)
214  */
215  Vector<Obj, 2, OTYPE> center() const {
216  assert(isValid());
217  return ((*this)[0] + (*this)[1]) / Obj(2);
218  }
219 };
220 
221 typedef Rectangle<double, long double> Rectd;
222 typedef Rectangle<float, double> Rectf;
223 typedef Rectangle<int, double> Recti;
224 typedef Rectangle<unsigned int, double> Rectui;
225 } // namespace tlp
226 #endif
227 ///@endcond
This class represents the 3D bounding box of an object. It is mostly used to determine whether or not...
Definition: BoundingBox.h:66