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  * Cylinder feature.
33  *
34  * Authors:
35  * Eric Marchand
36  *
37  *****************************************************************************/
38 
39 /*!
40   \file vpCylinder.h
41   \brief  class that defines what is a cylinder
42 */
43 
44 #ifndef vpCylinder_hh
45 #define vpCylinder_hh
46 
47 #include <math.h>
48 #include <visp3/core/vpHomogeneousMatrix.h>
49 #include <visp3/core/vpMath.h>
50 
51 #include <visp3/core/vpForwardProjection.h>
52 
53 /*!
54   \class vpCylinder
55   \ingroup group_core_geometry
56   \brief Class that defines a 3D cylinder in the object frame and allows forward projection of a 3D cylinder in the
57   camera frame and in the 2D image plane by perspective projection.
58   All the parameters must be set in meter.
59 
60   A 3D cylinder of radius R is defined by the set of circles of radius R whose center belongs
61   to a straight line perpendicular to the plane of the circles.
62 
63   A 3D cylinder has the followings parameters:
64   - **in the object frame**: the cylinder is represented by the equation:
65   \f$ (X - oX)^2 + (Y - oY)^2 + (Z - oZ)^2 - (oA \; X + oB \; Y + oC \; Z)^2 -
66   R^2 = 0 \f$ with
67   \f[
68   \left\{ \begin{array}{l}
69   oA^2 + oB^2 + oC^2 = 1  \\
70   oA \; oX + oB \; oY + oC \; oZ = 0
71   \end{array} \right.
72   \f]
73   where R is the radius of the cylinder, oA, oB, oC are the
74   coordinates of its direction vector and oX, oY, oZ are the
75   coordinates of the nearest point belonging to the cylinder axis from the
76   projection center.
77   The corresponding parameters are located in vpForwardProjection::oP 7-dim internal vector. They correspond
78   to oP = (oA, oB, oC, oX, oY, oZ, R).
79   Setting the cylinder parameters is achieved through the constructors with
80   parameters or setWorldCoordinates() methods.
81   To get theses parameters use get_oP().
82 
83   - **in the camera frame**: parameters are saved in vpTracker::cP 7-dim internal vector
84   with cP =(cA, cB, cC, cX, cY, cZ, R). Considering the set of parameters oP expressed in the object
85   frame, cylinder coordinates expressed in the camera frame are obtained using
86   changeFrame(). To get these parameters use get_cP().
87 
88   - **in the 2D image plane**: parameters are saved in vpTracker::p 4-dim vector.
89   They correspond to p = (\f$\rho_1\f$, \f$\theta_1\f$, \f$\rho_2\f$, \f$\theta_2\f$), noting
90   that for non-degenerated cases, the perspective projection of a cylinder on the image plane is a set of two
91   straight lines with equation:
92   \f[
93   \left\{ \begin{array}{lll}
94   x \;\cos\theta_1 + x \;\sin\theta_1 - \rho_1 = 0 \\
95   y \;\cos\theta_2 + y \;\sin\theta_2 - \rho_2 = 0
96   \end{array} \right.
97   \f]
98   Perspective projection is achieved using projection() methods. The methods
99   get_p(), getRho1(), getTheta1() and getRho2(), getTheta2() allow to access to the
100   projected line parameters.
101 */
102 class VISP_EXPORT vpCylinder : public vpForwardProjection
103 {
104 public:
105   typedef enum {
106     line1, /*!< First limb of the cylinder. */
107     line2  /*!< Second limb of the cylinder. */
108   } vpLineCylinderType;
109 
110   vpCylinder();
111   explicit vpCylinder(const vpColVector &oP);
112   vpCylinder(double oA, double oB, double oC, double oX, double oY, double oZ, double R);
113   virtual ~vpCylinder();
114 
115   void changeFrame(const vpHomogeneousMatrix &cMo, vpColVector &cP) const;
116   void changeFrame(const vpHomogeneousMatrix &cMo);
117 
118   double computeZ(double x, double y) const;
119 
120   void display(const vpImage<unsigned char> &I, const vpCameraParameters &cam, const vpColor &color = vpColor::green,
121                unsigned int thickness = 1);
122   void display(const vpImage<unsigned char> &I, const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
123                const vpColor &color = vpColor::green, unsigned int thickness = 1);
124 
125   vpCylinder *duplicate() const;
126 
127   /*!
128     Return the \f$\rho_1\f$ parameter of the line corresponding to the
129     projection of the cylinder in the image plane.
130     \sa getTheta1()
131     */
getRho1()132   double getRho1() const { return p[0]; }
133   /*!
134     Return the \f$\theta_1\f$ parameter of the line corresponding to the
135     projection of the cylinder in the image plane.
136     \sa getRho1()
137     */
getTheta1()138   double getTheta1() const { return p[1]; }
139 
140   /*!
141     Return the \f$\rho_2\f$ parameter of the line corresponding to the
142     projection of the cylinder in the image plane.
143     \sa getTheta2()
144     */
getRho2()145   double getRho2() const { return p[2]; }
146   /*!
147     Return the \f$\theta_2\f$ parameter of the line corresponding to the
148     projection of the cylinder in the image plane.
149     \sa getRho2()
150     */
getTheta2()151   double getTheta2() const { return p[3]; }
152 
153   /*!
154     Return cylinder cA parameter expressed in the camera frame.
155   */
getA()156   double getA() const { return cP[0]; }
157   /*!
158     Return cylinder cB parameter expressed in the camera frame.
159   */
getB()160   double getB() const { return cP[1]; }
161   /*!
162     Return cylinder cC parameter expressed in the camera frame.
163   */
getC()164   double getC() const { return cP[2]; }
165   /*!
166     Return cylinder cX parameter expressed in the camera frame.
167   */
getX()168   double getX() const { return cP[3]; }
169   /*!
170     Return cylinder cY parameter expressed in the camera frame.
171   */
getY()172   double getY() const { return cP[4]; }
173   /*!
174     Return cylinder cZ parameter expressed in the camera frame.
175   */
getZ()176   double getZ() const { return cP[5]; }
177   /*!
178     Return cylinder R parameter corresponding to the cylinder radius.
179   */
getR()180   double getR() const { return cP[6]; }
181 
182   void init();
183 
184   void projection();
185   void projection(const vpColVector &cP, vpColVector &p) const;
186 
187   void setWorldCoordinates(const vpColVector &oP);
188   void setWorldCoordinates(double oA, double oB, double oC, double oX, double oY, double oZ, double R);
189 };
190 
191 #endif
192