- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

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名前空間の始まり
45 _MIST_BEGIN
46
47
52 template < int K >
53 struct bspline_base
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:
171 enum BSplineMode
172 {
173 ROUND,
174 THROUGH,
175 };
176
177 protected:
178 knot_list knot_;
179 BSplineMode mode_;
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