DGtal  0.9.2
Ellipse2D.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file Ellipse2D.ih
19  * @author David Coeurjolly (\c david.coeurjolly@liris.cnrs.fr )
20  * Laboratoire d'InfoRmatique en Image et Systèmes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
21  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
22  * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
23  *
24  * @date 2011/04/12
25  *
26  * Implementation of inline methods defined in Ellipse2D.h
27  *
28  * This file is part of the DGtal library.
29  */
30 
31 
32 //////////////////////////////////////////////////////////////////////////////
33 #include <cstdlib>
34 //////////////////////////////////////////////////////////////////////////////
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // IMPLEMENTATION of inline methods.
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 ///////////////////////////////////////////////////////////////////////////////
41 // ----------------------- Standard services ------------------------------
42 
43 /**
44  * Destructor.
45  */
46 template <typename T>
47 inline
48 DGtal::Ellipse2D<T>::~Ellipse2D()
49 {
50 }
51 
52 template <typename T>
53 inline
54 DGtal::Ellipse2D<T>::Ellipse2D(const double x0, const double y0,
55  const double a0, const double a1, const double theta)
56  : myCenter(x0,y0), myAxis1(a0),myAxis2(a1),myTheta(theta)
57 {}
58 
59 
60 template <typename T>
61 inline
62 DGtal::Ellipse2D<T>::Ellipse2D(const RealPoint2D &aPoint,
63  const double a0, const double a1, const double theta)
64  : myCenter(aPoint), myAxis1(a0),myAxis2(a1),myTheta(theta)
65 {}
66 
67 template <typename T>
68 inline
69 DGtal::Ellipse2D<T>::Ellipse2D(const Point &aPoint,
70  const double a0, const double a1, const double theta)
71  : myAxis1(a0),myAxis2(a1),myTheta(theta)
72 {
73  myCenter = aPoint;
74 }
75 
76 /////////////////////////////////////////////////////////////////////////////
77 // ------------- Implementation of 'StarShaped' services ------------------
78 
79 /**
80  * @param p any point in the plane.
81  *
82  * @return the angle parameter between 0 and 2*Pi corresponding to
83  * this point for the shape.
84  */
85 template <typename T>
86 inline
87 double
88 DGtal::Ellipse2D<T>::parameter( const RealPoint2D & pp ) const
89 {
90  RealPoint2D v2d( pp );
91  v2d -= myCenter;
92 
93  double angle;
94 
95  if ( v2d[0] == 0.0 )
96  {
97  if ( v2d[1] >0 )
98  angle = M_PI/2.0;
99  else
100  angle = 1.5*M_PI;
101  }
102  else if ( ( v2d[0] > 0.0 ) && ( v2d[1] >= 0.0 ) )
103  angle = atan(v2d[1]/v2d[0]);
104  else if ( ( v2d[0] > 0.0 ) && ( v2d[1] <= 0.0 ) )
105  angle = 2*M_PI + atan(v2d[1]/v2d[0]);
106  else if ( ( v2d[0] < 0.0 ) && ( v2d[1] >= 0.0 ) )
107  angle = atan(v2d[1]/v2d[0]) + M_PI;
108  else // ( ( v2d[0] < 0.0 ) && ( v2d[1] <= 0.0 ) )
109  angle = atan(v2d[1]/v2d[0]) + M_PI;
110 
111  return angle;
112 }
113 
114 /**
115  * @param t any angle between 0 and 2*Pi.
116  *
117  * @return the vector (x(t),y(t)) which is the position on the
118  * shape boundary.
119  */
120 template <typename T>
121 inline
122 typename DGtal::Ellipse2D<T>::RealPoint2D
123 DGtal::Ellipse2D<T>::x( double t ) const
124 {
125  double a2 = myAxis1*myAxis1;
126  double b2 = myAxis2*myAxis2;
127  double costth = cos( t - myTheta );
128  // double sintth = sin( t - myTheta );
129  double cost = cos( t );
130  double sint = sin( t );
131  double rho = myAxis2 / sqrt( 1.0 - ((a2-b2)/a2)*costth*costth);
132  //myAxis2*myAxis1 / sqrt( a2 - (a2-b2)*costth*costth);
133  RealPoint2D v( rho*cost,
134  rho*sint );
135  v += myCenter;
136  return v;
137 }
138 
139 
140 /**
141  * @param t any angle between 0 and 2*Pi.
142  *
143  * @return the vector (x'(t),y'(t)) which is the tangent to the
144  * shape boundary.
145  */
146 template <typename T>
147 inline
148 typename DGtal::Ellipse2D<T>::RealVector2D
149 DGtal::Ellipse2D<T>::xp( const double t ) const
150 {
151  double a2 = myAxis1*myAxis1;
152  double b2 = myAxis2*myAxis2;
153  double costth = cos( t - myTheta );
154  double sintth = sin( t - myTheta );
155  double cost = cos( t );
156  double sint = sin( t );
157  double rho = myAxis2 / sqrt( 1.0 - ((a2-b2)/a2)*costth*costth);
158  double a = myAxis1;
159  double b = myAxis2;
160  double rhod= a*b*(b2-a2)*sintth*costth
161  / std::pow( a2*sintth*sintth + b2*costth*costth, 1.5 );
162  RealPoint2D v( rhod*cost - rho*sint, rhod*sint + rho*cost );
163 
164  return v;
165 }
166 
167 /**
168  * @param t any angle between 0 and 2*Pi.
169  *
170  * @return the vector (x''(t),y''(t)).
171  */
172 template <typename T>
173 inline
174 typename DGtal::Ellipse2D<T>::RealVector2D
175 DGtal::Ellipse2D<T>::xpp( const double t ) const
176 {
177  double a2 = myAxis1*myAxis1;
178  double b2 = myAxis2*myAxis2;
179  double costth = cos( t - myTheta );
180  double sintth = sin( t - myTheta );
181  double cost = cos( t );
182  double sint = sin( t );
183  double rho = myAxis2 / sqrt( 1.0 - ((a2-b2)/a2)*costth*costth);
184 
185  double a = myAxis1;
186  double b = myAxis2;
187  double rhod = a*b*(b2-a2)*sintth*costth
188  / std::pow( a2*sintth*sintth + b2*costth*costth, 1.5 );
189  double rhodd = a*b*(b2-a2)
190  / std::pow( a2*sintth*sintth + b2*costth*costth, 2.5 )
191  * ( (costth*costth - sintth*sintth) * (a2*sintth*sintth + b2*costth*costth)
192  + 3.0*(b2-a2)*sintth*sintth*costth*costth );
193 
194  RealPoint2D v( rhodd*cost - 2.0*rhod*sint - rho*cost,
195  rhodd*sint + 2.0*rhod*cost - rho*sint );
196  return v;
197 }
198 
199 
200 ///////////////////////////////////////////////////////////////////////////////
201 // Interface - public :
202 
203 /**
204  * Writes/Displays the object on an output stream.
205  * @param out the output stream where the object is written.
206  */
207 template <typename T>
208 inline
209 void
210 DGtal::Ellipse2D<T>::selfDisplay ( std::ostream & out ) const
211 {
212  out << "[Ellipse2D] center= "<<myCenter<<" big axis="<<myAxis1
213  <<" small axis="<<myAxis2<<" phase="<<myTheta;
214 }
215 
216 /**
217  * Checks the validity/consistency of the object.
218  * @return 'true' if the object is valid, 'false' otherwise.
219  */
220 template <typename T>
221 inline
222 bool
223 DGtal::Ellipse2D<T>::isValid() const
224 {
225  return true;
226 }
227 
228 
229 
230 ///////////////////////////////////////////////////////////////////////////////
231 // Implementation of inline functions //
232 
233 template <typename T>
234 inline
235 std::ostream&
236 DGtal::operator<< ( std::ostream & out,
237  const Ellipse2D<T> & object )
238 {
239  object.selfDisplay( out );
240  return out;
241 }
242 
243 // //
244 ///////////////////////////////////////////////////////////////////////////////
245 
246