bspline.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
33 
34 #ifndef __INCLUDE_BSPLINE__
35 #define __INCLUDE_BSPLINE__
36 
37 #ifndef __INCLUDE_MIST_CONF_H__
38 #include "config/mist_conf.h"
39 #endif
40 
41 #include <vector>
42 
43 
44 // mist名前空間の始まり
46 
47 
52 template < int K >
54 {
63  static double Base( const std::vector< double > &knot, std::vector< double >::size_type i, double t )
64  {
65  double B = 0.0;
66 
67  if( knot[ i + K - 1 ] - knot[ i ] != 0 )
68  {
69  B = ( t - knot[ i ] ) * bspline_base< K - 1 >::Base( knot, i, t ) / ( knot[ i + K - 1 ] - knot[ i ] );
70  }
71 
72  if( knot[ i + K ] - knot[ i + 1 ] != 0 )
73  {
74  B += ( knot[ i + K ] - t ) * bspline_base< K - 1 >::Base( knot, i + 1, t ) / ( knot[ i + K ] - knot[ i + 1 ] );
75  }
76  return( B );
77  }
78 };
79 
80 
85 template < >
86 struct bspline_base< 1 >
87 {
96  static double Base( const std::vector< double > &knot, std::vector< double >::size_type i, double t )
97  {
98  return( ( knot[ i ] <= t && t < knot[ i + 1 ] ) ? 1.0 : 0.0 );
99  }
100 };
101 
102 
105 
106 
107 
115 
116 
153 template < class T, int K, class Allocator = std::allocator< T > >
154 class bspline : public std::vector< T, Allocator >
155 {
156 private:
157  typedef std::vector< T, Allocator > base;
158  typedef typename base::allocator_type allocator_type;
159  typedef typename base::reference reference;
160  typedef typename base::const_reference const_reference;
161  typedef typename base::value_type value_type;
162  typedef typename base::size_type size_type;
163  typedef typename base::difference_type difference_type;
164  typedef typename base::pointer pointer;
165  typedef typename base::const_pointer const_pointer;
166 
167  typedef std::vector< double > knot_list;
168 
169 public:
172  {
175  };
176 
177 protected:
178  knot_list knot_;
180 
181 
182 public:
191  value_type operator( )( double t )
192  {
193  size_type n = base::size( ) - 1; // n + 1 は制御点の数
194  size_type m = n + K; // m + 1 はノットベクトルの数
195  if( knot_.size( ) < m + 1 )
196  {
197  // 不適切なノットベクトルが設定されています
198  knot( mode_ );
199  }
200  else if( base::empty( ) )
201  {
202  return( value_type( 0 ) );
203  }
204 
205  t *= static_cast< double >( m - 2 * K + 2 );
206 
207  // まず,ゼロ要素を作成する
208  value_type p = value_type( base::operator[]( 0 ) ) * 0;
209  for( size_type i = 0 ; i < base::size( ) ; i++ )
210  {
211  double B = bspline_base< K >::Base( knot_, i, t );
212  p += B * base::operator[]( i );
213  }
214 
215  return( p );
216  }
217 
224  void knot( const knot_list &kknot )
225  {
226  knot_ = kknot;
227  }
228 
235  void knot( BSplineMode mode )
236  {
237  size_type n = base::size( ) - 1; // n + 1 は制御点の数
238  size_type m = n + K; // m + 1 はノットベクトルの数
239  size_type i;
240 
241  knot_list kknot( m + 1 );
242  switch( mode )
243  {
244  case ROUND:
245  // リングの場合
246  for( i = 0 ; i <= m ; i++ )
247  {
248  kknot[ i ] = static_cast< double >( i - K + 1 );
249  }
250  break;
251 
252  case THROUGH:
253  // 最初と最後を通る曲線の場合
254  for( i = 0 ; i < K ; i++ )
255  {
256  kknot[ i ] = 0.0;
257  }
258  for( i = K ; i < m - K + 1 ; i++ )
259  {
260  kknot[ i ] = static_cast< double >( i - K + 1 );
261  }
262  for( i = m - K + 1 ; i <= m ; i++ )
263  {
264  kknot[ i ] = static_cast< double >( 2 + m - 2 * K );
265  }
266  break;
267  }
268 
269  knot( kknot );
270  }
271 
273  const bspline &operator =( const bspline &b )
274  {
275  if( this != &b )
276  {
277  base::operator =( b );
278  knot_ = b.knot_;
279  mode_ = b.mode_;
280  }
281  return( *this );
282  }
283 
285  bspline( const bspline &b ) : base( b ), knot_( b.knot_ ), mode_( b.mode_ )
286  {
287  }
288 
293  bspline( ) : mode_( THROUGH )
294  {
295  }
296 };
297 
299 // Bスプライングループの終わり
300 
301 
303 // 自由曲線・曲面グループの終わり
304 
305 
306 // mist名前空間の終わり
307 _MIST_END
308 
309 
310 #endif // __INCLUDE_BSPLINE__
311 

Generated on Wed Nov 12 2014 19:44:13 for MIST by doxygen 1.8.1.2