DGtal  1.2.0
LambdaMST3DBy2D.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 LambdaMST3DBy2D.ih
19  * @author Kacper Pluta (\c kacper.pluta@esiee.fr )
20  * Laboratoire d'Informatique Gaspard-Monge - LIGM, France
21  *
22  * @date 2015/06/16
23  *
24  * This file is part of the DGtal library.
25  */
26 
27 #include <stdexcept>
28 
29 namespace DGtal
30 {
31  inline
32  TangentFromDSS3DBy2DFunctor::Vector3D
33  TangentFromDSS3DBy2DFunctor::operator() ( MAIN_AXIS mainAxis, const Vector2D & v0, const Vector2D & v1 ) const
34  {
35  Vector3D tangent;
36  if ( mainAxis == X )
37  {
38  if ( v1[1] == 0 || ( v0[0] == 0 && v1[0] == 0 ) )
39  {
40  tangent[0] = v0[0];
41  tangent[1] = v0[1];
42  tangent[2] = v1[1];
43  }
44  else
45  {
46  if ( v0[1] == 0 )
47  {
48  tangent[0] = v1[0];
49  tangent[1] = 0;
50  tangent[2] = v1[1];
51  }
52  else
53  {
54  tangent[0] = v1[0] * v0[0];
55  tangent[1] = v1[0] * v0[1];
56  tangent[2] = v0[0] * v1[1];
57  }
58  }
59  }
60  else if ( mainAxis == Y )
61  {
62  if ( v0[0] == 0 || ( v1[0] == 0 && v0[1] == 0 ) )
63  {
64  tangent[0] = v0[0];
65  tangent[1] = v1[0];
66  tangent[2] = v1[1];
67  }
68  else
69  {
70  if ( v1[1] == 0 )
71  {
72  tangent[0] = v0[0];
73  tangent[1] = v0[1];
74  tangent[2] = 0;
75  }
76  else
77  {
78  tangent[0] = v1[0] * v0[0];
79  tangent[1] = v1[0] * v0[1];
80  tangent[2] = v0[1] * v1[1];
81  }
82  }
83  }
84  else
85  {
86  if ( v0[0] == 0 || ( v0[1] == 0 && v1[1] == 0 ) )
87  {
88  tangent[0] = v0[0];
89  tangent[1] = v1[0];
90  tangent[2] = v1[1];
91  }
92  else
93  {
94  if ( v1[0] == 0 )
95  {
96  tangent[0] = v0[0];
97  tangent[1] = 0;
98  tangent[2]= v0[1];
99  }
100  else
101  {
102  tangent[0] = v0[0] * v1[1];
103  tangent[1] = v1[0] * v0[1];
104  tangent[2] = v0[1] * v1[1];
105  }
106  }
107  }
108  return tangent;
109  }
110 
111 
112  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
113  inline
114  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::LambdaMST3DBy2DEstimator() : myBegin(), myEnd()
115  {
116  //projections
117  std::vector < Dimension > v1, v2, v3;
118  v1.push_back ( 0 );
119  v1.push_back ( 1 );
120  v2.push_back ( 0 );
121  v2.push_back ( 2 );
122  v3.push_back ( 1 );
123  v3.push_back ( 2 );
124  myProjXY.init ( v1.begin ( ), v1.end ( ) );
125  myProjXZ.init ( v2.begin ( ), v2.end ( ) );
126  myProjYZ.init ( v3.begin ( ), v3.end ( ) );
127  }
128 
129  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
130  inline
131  void
132  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::init ( Iterator3D itB, Iterator3D itE,
133  MAIN_AXIS axis )
134  {
135  myBegin = itB;
136  myEnd = itE;
137  myAxis = axis;
138  tXY.clear ( ); tYZ.clear ( ); tXZ.clear ( );
139  for ( auto it = myBegin; it != myEnd; ++it )
140  {
141  if ( axis == MAIN_AXIS::X )
142  {
143  tXY.push_back ( myProjXY ( *it ) );
144  tXZ.push_back ( myProjXZ ( *it ) );
145  }
146  else if ( axis == MAIN_AXIS::Y )
147  {
148  tXY.push_back ( myProjXY ( *it ) );
149  tYZ.push_back ( myProjYZ ( *it ) );
150  }
151  else
152  {
153  tXZ.push_back ( myProjXZ ( *it ) );
154  tYZ.push_back ( myProjYZ ( *it ) );
155  }
156  }
157  }
158 
159  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
160  inline
161  bool
162  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::isValid ( ) const
163  {
164  return ( myBegin != myEnd );
165  }
166 
167  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
168  inline
169  typename LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::RealVector3D
170  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::eval ( const Point3D & point )
171  {
172  assert ( isValid ( ) );
173  Iterator3D it = std::find ( myBegin, myEnd, point );
174  if ( it == myEnd )
175  throw std::runtime_error ( "L-MST3Dby2D::eval: The point does not belong to the curve!" );
176 
177  if ( myAxis == MAIN_AXIS::X )
178  return myFunctor ( MAIN_AXIS::X, Estimate2DTangent ( tXY.cbegin ( ), tXY.cend ( ), myProjXY ( *it ) ),
179  Estimate2DTangent ( tXZ.cbegin ( ), tXZ.cend ( ), myProjXZ ( *it ) ) );
180  else if ( myAxis == MAIN_AXIS::Y )
181  return myFunctor ( MAIN_AXIS::Y, Estimate2DTangent ( tXY.cbegin ( ), tXY.cend ( ), myProjXY ( *it ) ),
182  Estimate2DTangent ( tYZ.cbegin ( ), tYZ.cend ( ), myProjYZ ( *it ) ) );
183  else
184  return myFunctor ( MAIN_AXIS::Z, Estimate2DTangent ( tXZ.cbegin ( ), tXZ.cend ( ), myProjXZ ( *it ) ),
185  Estimate2DTangent ( tYZ.cbegin ( ), tYZ.cend ( ), myProjYZ ( *it ) ) );
186  }
187 
188  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
189  template < typename OutputIterator >
190  inline
191  OutputIterator
192  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::eval ( Iterator3D itb, Iterator3D ite,
193  OutputIterator result )
194  {
195  assert ( myBegin != myEnd && isValid() && myBegin <= itb && ite <= myEnd && itb != ite );
196  std::vector < RealVector2D > tangent1;
197  std::vector < RealVector2D > tangent2;
198 
199  auto offsetB = std::distance ( myBegin, itb );
200  auto offsetE = std::distance ( myEnd, ite );
201 
202  if ( myAxis == MAIN_AXIS::X )
203  {
204  Estimate2DTangent ( tXY.cbegin ( ) + offsetB, tXY.cend ( ) + offsetE, back_inserter ( tangent1 ) );
205  Estimate2DTangent ( tXZ.cbegin ( ) + offsetB, tXZ.cend ( ) + offsetE, back_inserter ( tangent2 ) );
206  }
207  else if ( myAxis == MAIN_AXIS::Y )
208  {
209  Estimate2DTangent ( tXY.cbegin ( ) + offsetB, tXY.cend ( ) + offsetE, back_inserter ( tangent1 ) );
210  Estimate2DTangent ( tYZ.cbegin ( ) + offsetB, tYZ.cend ( ) + offsetE, back_inserter ( tangent2 ) );
211  }
212  else
213  {
214  Estimate2DTangent ( tXZ.cbegin ( ) + offsetB, tXZ.cend ( ) + offsetE, back_inserter ( tangent1 ) );
215  Estimate2DTangent ( tYZ.cbegin ( ) + offsetB, tYZ.cend ( ) + offsetE, back_inserter ( tangent2 ) );
216  }
217 
218  for ( auto it = itb; it < ite; ++it )
219  result++ = myFunctor ( myAxis, tangent1[std::distance ( itb, it )], tangent2[std::distance ( itb, it )] );
220 
221  return result;
222  }
223 
224 
225  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
226  inline
227  typename LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::RealVector2D
228  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::Estimate2DTangent
229  ( const TCurve2D::const_iterator itb, TCurve2D::const_iterator ite, const Point2D & point )
230  {
231  Segmentation2D segmenter ( itb, ite, SegmentComputer2D ( ) );
232  TEstimator lmst;
233  lmst.attach ( segmenter );
234  lmst.init ( itb, ite );
235  return lmst.eval ( point );
236  }
237 
238 
239  template < typename Iterator3D, typename Functor, typename LambdaFunctor, int CONNECTIVITY >
240  template < typename OutputIterator >
241  inline
242  OutputIterator
243  LambdaMST3DBy2DEstimator< Iterator3D, Functor, LambdaFunctor, CONNECTIVITY >::Estimate2DTangent
244  ( TCurve2D::const_iterator itb, TCurve2D::const_iterator ite, OutputIterator result )
245  {
246  Segmentation2D segmenter ( itb, ite, SegmentComputer2D ( ) );
247  TEstimator lmst;
248  lmst.attach ( segmenter );
249  lmst.init ( itb, ite );
250  return lmst.eval ( itb, ite, result );
251  }
252 }