Visual Servoing Platform  version 3.5.1 under development (2023-05-30)
vpRectOriented.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 (possibly oriented) rectangle in the plane.
33  *
34  * Author:
35  * Pierre Chatelain
36  * Marc Pouliquen
37  *
38  *****************************************************************************/
39 #include <visp3/core/vpRectOriented.h>
40 
41 #include <cmath>
42 
45  : m_center(), m_width(), m_height(), m_theta(), m_topLeft(), m_topRight(), m_bottomLeft(), m_bottomRight()
46 {
47 }
48 
55 vpRectOriented::vpRectOriented(const vpImagePoint &center, double width, double height, double theta)
56 {
57  m_center = center;
58  m_width = width;
59  m_height = height;
60  m_theta = theta;
61  m_topLeft.set_i(m_center.get_i() - m_height * cos(m_theta) / 2.0 - m_width * sin(m_theta) / 2.0);
62  m_topLeft.set_j(m_center.get_j() + m_height * sin(m_theta) / 2.0 - m_width * cos(m_theta) / 2.0);
63  m_bottomLeft.set_i(m_center.get_i() + m_height * cos(m_theta) / 2.0 - m_width * sin(m_theta) / 2.0);
64  m_bottomLeft.set_j(m_center.get_j() - m_height * sin(m_theta) / 2.0 - m_width * cos(m_theta) / 2.0);
65  m_bottomRight.set_i(m_center.get_i() + m_height * cos(m_theta) / 2.0 + m_width * sin(m_theta) / 2.0);
66  m_bottomRight.set_j(m_center.get_j() - m_height * sin(m_theta) / 2.0 + m_width * cos(m_theta) / 2.0);
67  m_topRight.set_i(m_center.get_i() - m_height * cos(m_theta) / 2.0 + m_width * sin(m_theta) / 2.0);
68  m_topRight.set_j(m_center.get_j() + m_height * sin(m_theta) / 2.0 + m_width * cos(m_theta) / 2.0);
69 }
70 
75 {
76  m_center = rect.getCenter();
77  m_width = rect.getWidth();
78  m_height = rect.getHeight();
79  m_theta = .0;
80  m_topLeft.set_i(m_center.get_i() - m_height / 2.0);
81  m_topLeft.set_j(m_center.get_j() - m_width / 2.0);
82  m_bottomLeft.set_i(m_center.get_i() + m_height / 2.0);
83  m_bottomLeft.set_j(m_center.get_j() - m_width / 2.0);
84  m_bottomRight.set_i(m_center.get_i() + m_height / 2.0);
85  m_bottomRight.set_j(m_center.get_j() + m_width / 2.0);
86  m_topRight.set_i(m_center.get_i() - m_height / 2.0);
87  m_topRight.set_j(m_center.get_j() + m_width / 2.0);
88 }
89 
90 #if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
94 vpRectOriented::vpRectOriented(const vpRectOriented &rectOriented) { *this = rectOriented; }
95 
100 {
101  m_center = rectOriented.getCenter();
102  m_width = rectOriented.getWidth();
103  m_height = rectOriented.getHeight();
104  m_theta = rectOriented.getOrientation();
105  m_topLeft = rectOriented.getTopLeft();
106  m_bottomLeft = rectOriented.getBottomLeft();
107  m_bottomRight = rectOriented.getBottomRight();
108  m_topRight = rectOriented.getTopRight();
109  return *this;
110 }
111 #endif
112 
117 {
118  m_center = rect.getCenter();
119  m_width = rect.getWidth();
120  m_height = rect.getHeight();
121  m_theta = .0;
122  m_topLeft.set_i(m_center.get_i() - m_height / 2.0);
123  m_topLeft.set_j(m_center.get_j() - m_width / 2.0);
124  m_bottomLeft.set_i(m_center.get_i() + m_height / 2.0);
125  m_bottomLeft.set_j(m_center.get_j() - m_width / 2.0);
126  m_bottomRight.set_i(m_center.get_i() + m_height / 2.0);
127  m_bottomRight.set_j(m_center.get_j() + m_width / 2.0);
128  m_topRight.set_i(m_center.get_i() - m_height / 2.0);
129  m_topRight.set_j(m_center.get_j() + m_width / 2.0);
130  return *this;
131 }
132 
135 vpRectOriented::operator vpRect()
136 {
137  if (std::fabs(m_theta) > std::numeric_limits<double>::epsilon())
138  throw(vpException(vpException::badValue, "Cannot convert a vpRectOriented with non-zero orientation to a vpRect"));
139 
140  return vpRect(m_topLeft, m_bottomRight);
141 }
142 
147 void vpRectOriented::setPoints(const vpImagePoint &topLeft, const vpImagePoint &topRight,
148  const vpImagePoint &bottomLeft, const vpImagePoint &bottomRight)
149 {
150  m_topLeft = topLeft;
151  m_bottomLeft = bottomLeft;
152  m_bottomRight = bottomRight;
153  m_topRight = topRight;
154  m_center.set_i((m_topLeft.get_i() + m_bottomLeft.get_i() + m_bottomRight.get_i() + m_topRight.get_i()) / 4.0);
155  m_center.set_j((m_topLeft.get_j() + m_bottomLeft.get_j() + m_bottomRight.get_j() + m_topRight.get_j()) / 4.0);
156  m_width = sqrt((m_topRight.get_i() - m_topLeft.get_i()) * (m_topRight.get_i() - m_topLeft.get_i()) +
157  (m_topRight.get_j() - m_topLeft.get_j()) * (m_topRight.get_j() - m_topLeft.get_j()));
158  m_height = sqrt((m_bottomLeft.get_i() - m_topLeft.get_i()) * (m_bottomLeft.get_i() - m_topLeft.get_i()) +
159  (m_bottomLeft.get_j() - m_topLeft.get_j()) * (m_bottomLeft.get_j() - m_topLeft.get_j()));
160  m_theta = atan2(m_topRight.get_i() - m_topLeft.get_i(), m_topRight.get_j() - m_topLeft.get_j());
161 }
162 
165 {
166  m_topLeft += center - m_center;
167  m_bottomLeft += center - m_center;
168  m_bottomRight += center - m_center;
169  m_topRight += center - m_center;
170  m_center = center;
171 }
172 
174 vpImagePoint vpRectOriented::getCenter() const { return m_center; }
175 
177 vpImagePoint vpRectOriented::getTopLeft() const { return m_topLeft; }
178 
180 vpImagePoint vpRectOriented::getTopRight() const { return m_topRight; }
181 
183 vpImagePoint vpRectOriented::getBottomLeft() const { return m_bottomLeft; }
184 
186 vpImagePoint vpRectOriented::getBottomRight() const { return m_bottomRight; }
187 
189 void vpRectOriented::setSize(double width, double height)
190 {
191  m_width = width;
192  m_height = height;
193  m_topLeft.set_i(m_center.get_i() - m_height * cos(m_theta) / 2.0 - m_width * sin(m_theta) / 2);
194  m_topLeft.set_j(m_center.get_j() + m_height * sin(m_theta) / 2.0 - m_width * cos(m_theta) / 2);
195  m_bottomLeft.set_i(m_center.get_i() + m_height * cos(m_theta) / 2.0 - m_width * sin(m_theta) / 2);
196  m_bottomLeft.set_j(m_center.get_j() - m_height * sin(m_theta) / 2.0 - m_width * cos(m_theta) / 2);
197  m_bottomRight.set_i(m_center.get_i() + m_height * cos(m_theta) / 2.0 + m_width * sin(m_theta) / 2);
198  m_bottomRight.set_j(m_center.get_j() - m_height * sin(m_theta) / 2.0 + m_width * cos(m_theta) / 2);
199  m_topRight.set_i(m_center.get_i() - m_height * cos(m_theta) / 2.0 + m_width * sin(m_theta) / 2);
200  m_topRight.set_j(m_center.get_j() + m_height * sin(m_theta) / 2.0 + m_width * cos(m_theta) / 2);
201 }
202 
204 double vpRectOriented::getWidth() const { return m_width; }
205 
207 double vpRectOriented::getHeight() const { return m_height; }
208 
211 {
212  m_theta = theta;
213  m_topLeft.set_i(m_center.get_i() - m_height * cos(m_theta) / 2.0 - m_width * sin(m_theta) / 2);
214  m_topLeft.set_j(m_center.get_j() + m_height * sin(m_theta) / 2.0 - m_width * cos(m_theta) / 2);
215  m_bottomLeft.set_i(m_center.get_i() + m_height * cos(m_theta) / 2.0 - m_width * sin(m_theta) / 2);
216  m_bottomLeft.set_j(m_center.get_j() - m_height * sin(m_theta) / 2.0 - m_width * cos(m_theta) / 2);
217  m_bottomRight.set_i(m_center.get_i() + m_height * cos(m_theta) / 2.0 + m_width * sin(m_theta) / 2);
218  m_bottomRight.set_j(m_center.get_j() - m_height * sin(m_theta) / 2.0 + m_width * cos(m_theta) / 2);
219  m_topRight.set_i(m_center.get_i() - m_height * cos(m_theta) / 2.0 + m_width * sin(m_theta) / 2);
220  m_topRight.set_j(m_center.get_j() + m_height * sin(m_theta) / 2.0 + m_width * cos(m_theta) / 2);
221 }
222 
224 double vpRectOriented::getOrientation() const { return m_theta; }
225 
227 bool vpRectOriented::isInside(const vpImagePoint &point) const
228 {
229  if (!isLeft(point, m_topLeft, m_bottomLeft))
230  return false;
231  if (!isLeft(point, m_bottomLeft, m_bottomRight))
232  return false;
233  if (!isLeft(point, m_bottomRight, m_topRight))
234  return false;
235  if (!isLeft(point, m_topRight, m_topLeft))
236  return false;
237  return true;
238 }
239 
240 bool vpRectOriented::isLeft(const vpImagePoint &pointToTest, const vpImagePoint &point1,
241  const vpImagePoint &point2) const
242 {
243  double a = point1.get_j() - point2.get_j();
244  double b = point2.get_i() - point1.get_i();
245  double c = -(a * point1.get_i() + b * point1.get_j());
246  double d = a * pointToTest.get_i() + b * pointToTest.get_j() + c;
247  return (d > 0);
248 }
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:97
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:89
void set_j(double jj)
Definition: vpImagePoint.h:309
double get_j() const
Definition: vpImagePoint.h:132
void set_i(double ii)
Definition: vpImagePoint.h:298
double get_i() const
Definition: vpImagePoint.h:121
Defines an oriented rectangle in the plane.
double getHeight() const
Get the rectangle height.
vpImagePoint getBottomLeft() const
Get the bottom-left corner.
double getOrientation() const
Get the rectangle orientation (rad).
vpImagePoint getBottomRight() const
Get the bottom-right corner.
void setPoints(const vpImagePoint &topLeft, const vpImagePoint &topRight, const vpImagePoint &bottomLeft, const vpImagePoint &bottomRight)
void setCenter(const vpImagePoint &center)
Set the center of the rectangle.
double getWidth() const
Get the rectangle width.
bool isInside(const vpImagePoint &point) const
Check whether the point is inside the rectangle.
vpRectOriented()
Default constructor.
void setSize(double width, double height)
Set the size of the rectangle : performs a homothety relatively to the rectangle center.
vpImagePoint getTopRight() const
Get the top-right corner.
vpImagePoint getTopLeft() const
Get the top-left corner.
vpImagePoint getCenter() const
Get the rectangle center point.
vpRectOriented & operator=(const vpRectOriented &rect)=default
void setOrientation(double theta)
Set the rectangle orientation (rad).
Defines a rectangle in the plane.
Definition: vpRect.h:78
void getCenter(double &x, double &y) const
Definition: vpRect.h:135
double getWidth() const
Definition: vpRect.h:226
double getHeight() const
Definition: vpRect.h:165