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  * 2D point useful for image processing
33  *
34  * Authors:
35  * Nicolas Melchior
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
40 #ifndef vpImagePoint_H
41 #define vpImagePoint_H
42 
43 /*!
44   \file vpImagePoint.h
45   \brief Class that defines a 2D point in an image. This class is useful
46   for image processing
47 */
48 
49 #include <visp3/core/vpConfig.h>
50 
51 #include <cmath>  // std::fabs
52 #include <limits> // numeric_limits
53 #include <ostream>
54 #include <vector>
55 
56 class vpRect;
57 
58 /*!
59   \class vpImagePoint
60   \ingroup group_core_image
61 
62   \brief Class that defines a 2D point in an image. This class is
63   useful for image processing and stores only the <B>2D coordinates
64   given in sub-pixel</B>.
65 
66   \warning If you want to define a point thanks to its coordinates
67   given in meter in the object frame, the camera frame or the image
68   plane, you have to use the class vpPoint.
69 
70   In this class, the 2D coordinates are not necessary integer
71   values. It is easy to manipulate the given coordinates in the two
72   frames used in ViSP : the (i,j) coordinates and the (u,v)
73   coordinates.  The two following images illustrate the two coordinate
74   systems.
75 
76   \image html vpImagePoint.gif
77   \image latex vpImagePoint.ps  width=10cm
78 
79   \warning <B>An instance of the vpImagePoint class corresponds to a
80   particular point. Thus, if you change the point coordinate using the
81   method set_i(double i), it produces the same effect than if
82   you used the method set_v(double v). These two methods change
83   the same private attribute. It is also true for the two methods
84   set_j(double j) and set_u(double u).</B>
85 */
86 
87 class VISP_EXPORT vpImagePoint
88 {
89 public:
90   /*!
91     Default constructor that initialize the coordinates of the image
92     point to zero.
93   */
vpImagePoint()94   inline vpImagePoint() : i(0), j(0) {}
95   /*!
96     Default constructor that initialize the coordinates of the image
97     thanks to the parameters \f$ ii \f$ and \f$ jj \f$.
98   */
vpImagePoint(double ii,double jj)99   inline vpImagePoint(double ii, double jj) : i(ii), j(jj) {}
100   /*!
101     Copy constructor.
102 
103     Initialize the coordinates of the image point with \e ip.
104 
105     \param ip : An image point.
106   */
vpImagePoint(const vpImagePoint & ip)107   inline vpImagePoint(const vpImagePoint &ip) : i(ip.i), j(ip.j) {}
108   //! Destructor.
~vpImagePoint()109   inline virtual ~vpImagePoint() { }
110 
111   /*!
112     Copy operator.
113   */
114   inline vpImagePoint &operator=(const vpImagePoint &ip)
115   {
116     this->i = ip.i;
117     this->j = ip.j;
118     return *this;
119   }
120 #if (VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11)
121   /*!
122     Move operator.
123   */
124   inline vpImagePoint &operator=(const vpImagePoint &&ip) noexcept
125   {
126     this->i = ip.i;
127     this->j = ip.j;
128     return *this;
129   }
130 #endif
131 
132   vpImagePoint &operator+=(const vpImagePoint &ip);
133 
134   /*!
135 
136     Operator -=.
137 
138   */
139   inline vpImagePoint &operator-=(const vpImagePoint &ip)
140   {
141     this->i -= ip.i;
142     this->j -= ip.j;
143     return *this;
144   }
145   vpImagePoint &operator/=(double scale);
146   /*!
147 
148     Operator *=.
149   */
150   inline vpImagePoint &operator*=(double scale)
151   {
152     this->i *= scale;
153     this->j *= scale;
154     return *this;
155   }
156 
157   /*!
158 
159     Sets the point coordinate corresponding to the \f$ i \f$ axes in
160     the frame (i,j).
161 
162     \param ii : The desired value for the coordinate along the \f$ i \f$ axes.
163 
164     \sa set_j(), set_u(), set_v()
165   */
set_i(double ii)166   inline void set_i(double ii) { this->i = ii; }
167 
168   /*!
169 
170     Sets the point coordinate corresponding to the \f$ j \f$ axes in
171     the frame (i,j).
172 
173     \param jj : The desired value for the coordinate along the \f$ j \f$ axes.
174 
175     \sa set_i(), set_u(), set_v()
176   */
set_j(double jj)177   inline void set_j(double jj) { this->j = jj; }
178 
179   /*!
180 
181     Sets the point coordinates in the frame (i,j).
182 
183     \param ii : The desired value for the coordinate along the \f$ i \f$ axes.
184     \param jj : The desired value for the coordinate along the \f$ j \f$ axes.
185 
186     \sa set_i(), set_j(), set_u(), set_v()
187   */
set_ij(double ii,double jj)188   inline void set_ij(double ii, double jj)
189   {
190     this->i = ii;
191     this->j = jj;
192   }
193 
194   /*!
195 
196     Gets the point coordinate corresponding to the \f$ i \f$ axes in
197     the frame (i,j).
198 
199     \return The value of the coordinate along the \f$ i \f$ axes.
200 
201     \sa get_j(), get_u(), get_v()
202   */
get_i()203   inline double get_i() const { return i; }
204 
205   /*!
206 
207     Gets the point coordinate corresponding to the \f$ j \f$ axes in
208     the frame (i,j).
209 
210     \return The value of the coordinate along the \f$ j \f$ axes.
211 
212     \sa get_i(), get_u(), get_v()
213   */
get_j()214   inline double get_j() const { return j; }
215 
216   /*!
217 
218     Sets the point coordinate corresponding to the \f$ u \f$ axes in
219     the frame (u,v).
220 
221     \param u : The desired value for the coordinate along the \f$ u \f$ axes.
222 
223     \sa set_i(), set_j(), set_v()
224   */
set_u(double u)225   inline void set_u(double u) { j = u; }
226 
227   /*!
228 
229     Sets the point coordinate corresponding to the \f$ v \f$ axes in
230     the frame (u,v).
231 
232     \param v : The desired value for the coordinate along the \f$ v \f$ axes.
233 
234     \sa set_i(), set_j(), set_u()
235   */
set_v(double v)236   inline void set_v(double v) { i = v; }
237 
238   /*!
239 
240     Sets the point coordinates in the frame (u,v).
241 
242     \param u : The desired value for the coordinate along the \f$ u \f$ axes.
243     \param v : The desired value for the coordinate along the \f$ v \f$ axes.
244 
245     \sa set_i(), set_j(), set_u(), set_v()
246   */
set_uv(double u,double v)247   inline void set_uv(double u, double v)
248   {
249     this->i = v;
250     this->j = u;
251   }
252 
253   /*!
254 
255     Gets the point coordinate corresponding to the \f$ u \f$ axes in
256     the frame (u,v).
257 
258     \return The value of the coordinate along the \f$ u \f$ axes.
259 
260     \sa get_i(), get_j(), get_v()
261   */
get_u()262   inline double get_u() const { return j; }
263 
264   /*!
265 
266     Gets the point coordinate corresponding to the \f$ v \f$ axes in
267     the frame (u,v).
268 
269     \return The value of the coordinate along the \f$ v \f$ axes.
270 
271     \sa get_i(), get_j(), get_u()
272   */
get_v()273   inline double get_v() const { return i; }
274 
275   static vpRect getBBox(const std::vector<vpImagePoint> &ipVec);
276 
277   static double distance(const vpImagePoint &iP1, const vpImagePoint &iP2);
278   static double sqrDistance(const vpImagePoint &iP1, const vpImagePoint &iP2);
279 
280   bool inRectangle(const vpRect &rect) const;
281 
282   friend VISP_EXPORT bool operator==(const vpImagePoint &ip1, const vpImagePoint &ip2);
283   friend VISP_EXPORT bool operator!=(const vpImagePoint &ip1, const vpImagePoint &ip2);
284   friend VISP_EXPORT vpImagePoint operator+=(const vpImagePoint &ip1, const vpImagePoint &ip2);
285   friend VISP_EXPORT vpImagePoint operator+(const vpImagePoint &ip1, const vpImagePoint &ip2);
286   friend VISP_EXPORT vpImagePoint operator+(const vpImagePoint &ip1, int offset);
287   friend VISP_EXPORT vpImagePoint operator+(const vpImagePoint &ip1, unsigned int offset);
288   friend VISP_EXPORT vpImagePoint operator+(const vpImagePoint &ip1, double offset);
289   friend VISP_EXPORT vpImagePoint operator-(const vpImagePoint &ip1, const vpImagePoint &ip2);
290   friend VISP_EXPORT vpImagePoint operator-(const vpImagePoint &ip1, int offset);
291   friend VISP_EXPORT vpImagePoint operator-(const vpImagePoint &ip1, unsigned int offset);
292   friend VISP_EXPORT vpImagePoint operator-(const vpImagePoint &ip1, double offset);
293   friend VISP_EXPORT vpImagePoint operator*(const vpImagePoint &ip1, double scale);
294   friend VISP_EXPORT vpImagePoint operator/(const vpImagePoint &ip1, double scale);
295   friend VISP_EXPORT std::ostream &operator<<(std::ostream &os, const vpImagePoint &ip);
296 
297 private:
298   double i, j;
299 };
300 
301 #endif
302