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.
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.
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/>.
18 * @file MeasureOfStraightLines.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
24 * Implementation of inline methods defined in MeasureOfStraightLines.h
26 * This file is part of the DGtal library.
29 ///////////////////////////////////////////////////////////////////////////////
30 // IMPLEMENTATION of inline methods.
31 ///////////////////////////////////////////////////////////////////////////////
33 //////////////////////////////////////////////////////////////////////////////
38 #include <boost/math/special_functions/asinh.hpp>
40 //////////////////////////////////////////////////////////////////////////////
42 ///////////////////////////////////////////////////////////////////////////////
43 // Internal functions //
50 DGtal::MeasureOfStraightLines::MeasureOfStraightLines()
61 DGtal::MeasureOfStraightLines:: ~MeasureOfStraightLines()
66 * Writes/Displays the object on an output stream.
67 * @param out the output stream where the object is written.
71 DGtal::MeasureOfStraightLines::selfDisplay( std::ostream & out ) const
73 out << "[MeasureOfStraightLines]";
77 * Checks the validity/consistency of the object.
78 * @return 'true' if the object is valid, 'false' otherwise.
82 DGtal::MeasureOfStraightLines::isValid() const
88 /// Compute the measure associated to the Edge (a0,b0) -- (a1,b1) in the (a,b)-space
91 DGtal::MeasureOfStraightLines::computeMeasureEdge ( double a0,double b0, double a1, double b1 )
95 //Aligned with the 'b' axis
96 if ( ( b0 == 0 ) && ( b1 == 0 ) )
98 //Aligned with the 'b' axis
99 if ( ( a0 == 0 ) && ( a1 == 0 ) )
102 double delta = ( a0*b1 - a1*b0 );
105 return delta * ( 1.0/ ( 1.0 + sqrt ( 1 + pow ( a1,2 ) ) ) );
107 return delta * ( ( -1.0 + sqrt ( 1.0 + pow ( a0,2 ) ) ) /pow ( a0,2 ) );
111 return delta * ( ( a0 - a1 + sqrt ( 1 + pow ( a0,2 ) ) *a1 - a0*sqrt ( 1 + pow ( a1,2 ) ) ) / ( pow ( a0,2 ) *a1 - a0*pow ( a1,2 ) ) );
114 return delta * a1/ ( a0* ( 1 + pow ( a1,2 ) + sqrt ( 1 + pow ( a1,2 ) ) ) );
119 * Set the epsilon threshold in the numerical approximation.
121 * @param aValue the new epsilon value
124 DGtal::MeasureOfStraightLines::setEpsilon(const double aValue)
129 ///////////////////////////////////////////////////////////////////////////////
130 // Implementation of inline methods //
133 * Compute the measure of the polygon {(a_i,b_i)} in the (a,b)-parameter space
134 * @param a the a-value of polygon vertices
135 * @param b the b-value of polygon vertices
137 * @return the measure value (positive value)
140 DGtal::MeasureOfStraightLines::computeMeasure(const std::vector<double> &a,
141 const std::vector<double> &b)
145 ASSERT(a.size() == b.size());
147 for (unsigned int i=0 ; i < a.size() ; i++)
149 measure += computeMeasureEdge ( a[i], b[i],
150 a[ ( i+1 ) % a.size()],b[ ( i+1 ) %a.size()] );
157 * Compute the abscissa of the centroid of the polygon {(a_i,b_i)} in the (a,b)-parameter space
158 * @param a the a-value of polygon vertices
159 * @param b the b-value of polygon vertices
161 * @return the measure value (positive value)
164 DGtal::MeasureOfStraightLines::computeCentroidA(const std::vector<double> &a,
165 const std::vector<double> &b)
170 ASSERT(a.size() == b.size());
172 for (unsigned int i=0 ; i < a.size() ; i++)
174 measure += computeMeasureEdge( a[i], b[i],
175 a[ ( i+1 ) % a.size()],b[ ( i+1 ) %a.size()] );
176 C_a += computeCentroidEdge_a ( a[i], b[i],
177 a[ ( i+1 ) % a.size()],b[ ( i+1 ) %a.size()] );
184 * Compute the abscissa of the centroid of the polygon {(a_i,b_i)} in the (a,b)-parameter space
185 * @param a the a-value of polygon vertices
186 * @param b the b-value of polygon vertices
188 * @return the measure value (positive value)
191 DGtal::MeasureOfStraightLines::computeCentroidB(const std::vector<double> &a,
192 const std::vector<double> &b)
197 ASSERT(a.size() == b.size());
199 for (unsigned int i=0 ; i < a.size() ; i++)
201 measure += computeMeasureEdge( a[i], b[i],
202 a[ ( i+1 ) % a.size()],b[ ( i+1 ) %a.size()] );
203 C_b += computeCentroidEdge_b ( a[i], b[i],
204 a[ ( i+1 ) % a.size()],b[ ( i+1 ) %a.size()] );
212 /// Compute the centroid on 'b' on the rectangular domain with vertices (x1,,y1) - (x2,y2)
213 /// PRECONDITION: y1<y2
218 DGtal::MeasureOfStraightLines::__computeCentroidSquare_b ( double x1, double y1, double x2,double y2 )
221 val = ( ( -1.0* ( sqrt ( 1.0 + pow ( x1,2 ) ) *x2 ) + x1*sqrt ( 1 + pow ( x2,2 ) ) ) * ( pow ( y1,2 ) - pow ( y2,2 ) ) ) / ( 2.0*sqrt ( ( 1.0 + pow ( x1,2 ) ) * ( 1.0 + pow ( x2,2 ) ) ) );
230 DGtal::MeasureOfStraightLines::sign ( const double a )
240 /// Approximate the centroid on 'b' on the trapezioid (a0,0)-(a0,b0)-(a1,b1)-(a1,0)
241 /// (internal function)
245 DGtal::MeasureOfStraightLines::__computeCentroidEdgeApprox_b ( double a0, double b0,double a1,double b1 )
248 unsigned int nb_step;
261 nb_step = ( unsigned int ) floor ( fabs ( a1-a0 ) /myEpsilon );
262 double slope = ( b1-b0 ) / ( a1-a0 );
263 double decal = b1 - ( b1-b0 ) / ( a1-a0 ) *a1;
266 return __computeCentroidSquare_b ( a0, 0, a1, b0 );
268 for ( unsigned int i=0; i < nb_step ; i++ )
270 y2 = ( b1-b0 ) / ( a1-a0 ) * ( a0+ ( i+1 ) *myEpsilon ) + decal;
272 measure += __computeCentroidSquare_b ( a0+i*myEpsilon, 0, a0+ ( i+1 ) *myEpsilon, y2 );
274 measure += __computeCentroidSquare_b ( a0+i*myEpsilon, y2, a0+ ( i+1 ) *myEpsilon, 0 );
280 /// Approximate the centroid on 'b' on the triangle (0,0)-(a0,b0)-(a1,b1)
281 /// (internal function)
285 DGtal::MeasureOfStraightLines::__computeCentroidTriApprox_b ( double a0, double b0,double a1,double b1 )
287 int signe = sign ( a0*b1 - a1*b0 );
290 double m_A0A1=0, m_0A0=0, m_0A1=0;
291 if ( ( b0 != 0 ) && ( a0 != 0 ) )
292 m_0A0 = __computeCentroidEdgeApprox_b ( 0,0,a0,b0 );
293 if ( ( b1 != 0 ) && ( a1 != 0 ) )
294 m_0A1 = __computeCentroidEdgeApprox_b ( 0,0,a1,b1 );
296 m_A0A1 = __computeCentroidEdgeApprox_b ( a0,b0,a1,b1 );
300 ASSERT ( m_A0A1>=0 );
304 double det = ( a1 * ( b0 - b1 ) - b1* ( a0 - a1 ) );
306 measure = m_0A0 + m_A0A1 - m_0A1;
308 measure = m_0A1 - m_0A0 - m_A0A1;
312 double det = ( a0 * ( b1 - b0 ) - b0* ( a1 - a0 ) );
314 measure = m_0A1 + m_A0A1 - m_0A0;
316 measure = m_0A0 - m_0A1 - m_A0A1;
318 ASSERT ( measure>=0 );
319 return signe*measure;
323 /// Compute the centroid on 'b' on the triangle (0,0)-(a0,b0)-(a1,b1)
327 DGtal::MeasureOfStraightLines::computeCentroidEdge_b ( double a0,double b0, double a1, double b1 )
330 double delta= ( a0*b1 - a1*b0 );
332 if ( ( b0 == 0 ) && ( b1 == 0 ) )
334 if ( ( a0 == 0 ) && ( a1 == 0 ) )
338 return delta* ( a1* ( ( -2 + sqrt ( 1 + a1*a1 ) ) *b0 + 2*b1 ) + ( b0 - 2*b1 ) *boost::math::asinh ( a1 ) ) / ( 2*a1*a1*a1 );
340 return delta* ( a0* ( 2*b0 + ( -2 + sqrt ( 1 + a0*a0 ) ) *b1 ) + ( -2*b0 + b1 ) *boost::math::asinh ( a0 ) ) / ( 2*a0*a0*a0 );
343 return delta* ( ( - ( ( a1* ( b0 + a1* ( -a1 + sqrt ( 1 + pow ( a1,-2 ) ) *sqrt ( 1 + pow ( a1,2 ) ) ) *
344 b1 ) ) /sqrt ( 1.0 + pow ( a1,2 ) ) ) + ( b0 + b1 ) *boost::math::asinh ( a1 ) ) /
345 ( 2.*pow ( a1,3 ) ) );
347 return __computeCentroidTriApprox_b ( a0,b0,a1,b1 );
352 /// Compute the centroid on 'a' on the triangle (0,0)-(a0,b0)-(a1,b1)
356 DGtal::MeasureOfStraightLines::computeCentroidEdge_a ( double a0,double b0, double a1, double b1 )
359 double delta= ( a0*b1 - a1*b0 );
361 if ( ( b0 == 0 ) && ( b1 == 0 ) )
363 if ( ( a0 == 0 ) && ( a1 == 0 ) )
367 return delta* ( a1 - boost::math::asinh ( a1 ) ) / ( a1*a1 );
369 return delta* ( a0 - boost::math::asinh ( a0 ) ) / ( a0*a0 );
372 return delta* ( ( -sqrt ( 1 + pow ( a1,-2 ) ) - 1.0/ ( a1*sqrt ( 1 + pow ( a1,2 ) ) ) + a1/sqrt ( 1 + pow ( a1,2 ) ) +
373 ( 2*boost::math::asinh ( a1 ) ) /pow ( a1,2 ) ) /2. );
375 return delta* ( ( - ( a1*boost::math::asinh ( a0 ) ) + a0*boost::math::asinh ( a1 ) ) / ( a0* ( a0 - a1 ) *a1 ) );
381 ///////////////////////////////////////////////////////////////////////////////
382 // Implementation of inline functions and external operators //
385 * Overloads 'operator<<' for displaying objects of class 'MeasureOfStraightLines'.
386 * @param out the output stream where the object is written.
387 * @param object the object of class 'MeasureOfStraightLines' to write.
388 * @return the output stream after the writing.
392 DGtal::operator<<( std::ostream & out,
393 const DGtal::MeasureOfStraightLines & object )
395 object.selfDisplay( out );
400 ///////////////////////////////////////////////////////////////////////////////