Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
vpRect.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Defines a rectangle in the plane.
33  *
34  * Author:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
45 #include <visp3/core/vpDebug.h>
46 #include <visp3/core/vpRect.h>
47 
53 vpRect::vpRect() : left(0), top(0), width(0), height(0) {}
54 
64 vpRect::vpRect(double l, double t, double w, double h) : left(l), top(t), width(w), height(h) {}
65 
74 vpRect::vpRect(const vpImagePoint &topLeft, double w, double h)
75  : left(topLeft.get_u()), top(topLeft.get_v()), width(w), height(h)
76 {
77 }
78 
83 vpRect::vpRect(const vpImagePoint &topLeft, const vpImagePoint &bottomRight)
84  : left(topLeft.get_u()), top(topLeft.get_v()), width(0), height(0)
85 {
86  this->left = topLeft.get_u();
87  this->top = topLeft.get_v();
88 
89  setBottom(bottomRight.get_v());
90  setRight(bottomRight.get_u());
91 }
92 
96 vpRect::vpRect(const vpRect &r) : left(0), top(0), width(0), height(0) { *this = r; }
97 
103 {
104  this->left = r.left;
105  this->top = r.top;
106  this->width = r.width;
107  this->height = r.height;
108  return *this;
109 }
110 
116 vpRect::vpRect(const std::vector<vpImagePoint> &ip) : left(0), top(0), width(0), height(0) { set(ip); }
117 
125 bool vpRect::isInside(const vpImagePoint &ip) const
126 {
127  return (ip.get_i() <= this->getBottom() && ip.get_i() >= this->getTop() && ip.get_j() <= this->getRight() &&
128  ip.get_j() >= this->getLeft());
129 }
130 
139 void vpRect::set(double l, double t, double w, double h)
140 {
141  left = l;
142  top = t;
143  width = w;
144  height = h;
145 }
146 
155 void vpRect::set(const vpImagePoint &topLeft, double w, double h)
156 {
157  left = topLeft.get_u();
158  top = topLeft.get_v();
159  width = w;
160  height = h;
161 }
162 
168 void vpRect::set(const std::vector<vpImagePoint> &ip)
169 {
170  if (ip.size() < 1)
171  throw(vpException(vpException::dimensionError, "At least 1 point is requested to build a rectangle"));
172  double minu, maxu;
173  double minv, maxv;
174  minu = maxu = ip[0].get_u();
175  minv = maxv = ip[0].get_v();
176 
177  for (size_t i = 1; i < ip.size(); i++) {
178  double u = ip[i].get_u();
179  double v = ip[i].get_v();
180  if (u < minu)
181  minu = u;
182  else if (u > maxu)
183  maxu = u;
184  if (v < minv)
185  minv = v;
186  else if (v > maxv)
187  maxv = v;
188  }
189 
190  setLeft(minu);
191  setTop(minv);
192  setRight(maxu);
193  setBottom(maxv);
194 }
195 
203 void vpRect::set(const vpImagePoint &topLeft, const vpImagePoint &bottomRight)
204 {
205  this->left = topLeft.get_u();
206  this->top = topLeft.get_v();
207 
208  setBottom(bottomRight.get_v());
209  setRight(bottomRight.get_u());
210 }
211 
215 void vpRect::set(const vpRect &r) { *this = r; }
216 
221 bool vpRect::operator==(const vpRect &r) const
222 {
223  // return (top == r.top && left == r.left && width == r.width && height ==
224  // r.height);
225  return (std::fabs(top - r.top) <= std::fabs(top) * std::numeric_limits<double>::epsilon() &&
226  std::fabs(left - r.left) <= std::fabs(left) * std::numeric_limits<double>::epsilon() &&
227  std::fabs(width - r.width) <= std::fabs(width) * std::numeric_limits<double>::epsilon() &&
228  std::fabs(height - r.height) <= std::fabs(height) * std::numeric_limits<double>::epsilon());
229 }
230 
235 bool vpRect::operator!=(const vpRect &r) const
236 {
237  // return (top != r.top || left != r.left || width != r.width || height !=
238  // r.height);
239  // return (std::fabs(top-r.top) >
240  // std::fabs(top)*std::numeric_limits<double>::epsilon()
241  // || std::fabs(left-r.left) >
242  // std::fabs(left)*std::numeric_limits<double>::epsilon()
243  // || std::fabs(width-r.width) >
244  // std::fabs(width)*std::numeric_limits<double>::epsilon()
245  // || std::fabs(height-r.height) >
246  // std::fabs(height)*std::numeric_limits<double>::epsilon());
247  return !(*this == r);
248 }
249 
257 {
258  double x1 = (std::max)(left, r.left);
259  double y1 = (std::max)(top, r.top);
260  width = (std::min)(left + width, r.left + r.width) - x1;
261  height = (std::min)(top + height, r.top + r.height) - y1;
262  left = x1;
263  top = y1;
264 
265  if (width <= 0 || height <= 0) {
266  *this = vpRect();
267  }
268 
269  return *this;
270 }
271 
277 vpRect vpRect::operator&(const vpRect &r) const
278 {
279  vpRect a = *this;
280  return a &= r;
281 }
282 
291 VISP_EXPORT bool inRectangle(const vpImagePoint &ip, const vpRect &rect)
292 {
293  return (ip.get_i() <= rect.getBottom() && ip.get_i() >= rect.getTop() && ip.get_j() <= rect.getRight() &&
294  ip.get_j() >= rect.getLeft());
295 }
296 
297 VISP_EXPORT std::ostream &operator<<(std::ostream &os, const vpRect &r)
298 {
299  os << r.getLeft() << ", " << r.getTop() << ", " << r.getWidth() << ", " << r.getHeight();
300  return os;
301 }
double get_i() const
Definition: vpImagePoint.h:204
double getTop() const
Definition: vpRect.h:192
void setLeft(double pos)
Definition: vpRect.h:289
error that can be emited by ViSP classes.
Definition: vpException.h:71
double getRight() const
Definition: vpRect.h:179
bool operator!=(const vpRect &r) const
Definition: vpRect.cpp:235
double get_u() const
Definition: vpImagePoint.h:263
void setTop(double pos)
Definition: vpRect.h:325
void set(double left, double top, double width, double height)
Definition: vpRect.cpp:139
double getWidth() const
Definition: vpRect.h:227
double get_j() const
Definition: vpImagePoint.h:215
vpRect operator &(const vpRect &r) const
bool isInside(const vpImagePoint &ip) const
Definition: vpRect.cpp:125
vpRect()
Definition: vpRect.cpp:53
double getLeft() const
Definition: vpRect.h:173
friend VISP_EXPORT bool inRectangle(const vpImagePoint &ip, const vpRect &rect)
Definition: vpRect.cpp:291
vpRect & operator &=(const vpRect &r)
void setRight(double pos)
Definition: vpRect.h:316
friend VISP_EXPORT std::ostream & operator<<(std::ostream &os, const vpRect &r)
Definition: vpRect.cpp:297
double getHeight() const
Definition: vpRect.h:166
Defines a rectangle in the plane.
Definition: vpRect.h:78
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
double getBottom() const
Definition: vpRect.h:97
vpRect & operator=(const vpRect &r)
Definition: vpRect.cpp:102
void setBottom(double pos)
Definition: vpRect.h:256
double get_v() const
Definition: vpImagePoint.h:274
bool operator==(const vpRect &r) const
Definition: vpRect.cpp:221