34 #ifndef __INCLUDE_SPLINE__
35 #define __INCLUDE_SPLINE__
37 #ifndef __INCLUDE_MIST_CONF_H__
41 #ifndef __INCLUDE_MIST_TYPE_TRAIT_H__
45 #ifndef __INCLUDE_MIST_VECTOR__
55 namespace __spline_utility__
58 struct arithmetic_operation
61 static const T add(
const T &v1,
const typename type_trait< T >::value_type &v2 ){
return( v1 + v2 ); }
63 static const T sub(
const T &v1,
const typename type_trait< T >::value_type &v2 ){
return( v1 - v2 ); }
65 static const T mul(
const T &v1,
const typename type_trait< T >::value_type &v2 ){
return( v1 * v2 ); }
67 static const T div(
const T &v1,
const typename type_trait< T >::value_type &v2 ){
return( v1 / v2 ); }
71 struct arithmetic_operation< vector3< T > >
74 static const vector3< T > add(
const vector3< T > &v1,
const vector3< T > &v2 ){
return( vector3< T >( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z ) ); }
76 static const vector3< T > add(
const vector3< T > &v1,
const typename vector3< T >::value_type &val ){
return( vector3< T >( v1.x + val, v1.y + val, v1.z + val ) ); }
78 static const vector3< T > sub(
const vector3< T > &v1,
const vector3< T > &v2 ){
return( vector3< T >( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z ) ); }
80 static const vector3< T > sub(
const vector3< T > &v1,
const typename vector3< T >::value_type &val ){
return( vector3< T >( v1.x - val, v1.y - val, v1.z - val ) ); }
82 static const vector3< T > mul(
const vector3< T > &v1,
const vector3< T > &v2 ){
return( vector3< T >( v1.x * v2.x, v1.y * v2.y, v1.z * v2.z ) ); }
84 static const vector3< T > mul(
const vector3< T > &v1,
const typename vector3< T >::value_type &val ){
return( vector3< T >( v1.x * val, v1.y * val, v1.z * val ) ); }
86 static const vector3< T > div(
const vector3< T > &v1,
const vector3< T > &v2 ){
return( vector3< T >( v1.x / v2.x, v1.y / v2.y, v1.z / v2.z ) ); }
88 static const vector3< T > div(
const vector3< T > &v1,
const typename vector3< T >::value_type &val ){
return( vector3< T >( v1.x / val, v1.y / val, v1.z / val ) ); }
92 struct arithmetic_operation< vector2< T > >
95 static const vector2< T > add(
const vector2< T > &v1,
const vector2< T > &v2 ){
return( vector2< T >( v1.x + v2.x, v1.y + v2.y ) ); }
97 static const vector2< T > add(
const vector2< T > &v1,
const typename vector2< T >::value_type &val ){
return( vector2< T >( v1.x + val, v1.y + val ) ); }
99 static const vector2< T > sub(
const vector2< T > &v1,
const vector2< T > &v2 ){
return( vector2< T >( v1.x - v2.x, v1.y - v2.y ) ); }
101 static const vector2< T > sub(
const vector2< T > &v1,
const typename vector2< T >::value_type &val ){
return( vector2< T >( v1.x - val, v1.y - val ) ); }
103 static const vector2< T > mul(
const vector2< T > &v1,
const vector2< T > &v2 ){
return( vector2< T >( v1.x * v2.x, v1.y * v2.y ) ); }
105 static const vector2< T > mul(
const vector2< T > &v1,
const typename vector2< T >::value_type &val ){
return( vector2< T >( v1.x * val, v1.y * val ) ); }
107 static const vector2< T > div(
const vector2< T > &v1,
const vector2< T > &v2 ){
return( vector2< T >( v1.x / v2.x, v1.y / v2.y ) ); }
109 static const vector2< T > div(
const vector2< T > &v1,
const typename vector2< T >::value_type &val ){
return( vector2< T >( v1.x / val, v1.y / val ) ); }
113 struct arithmetic_operation< array< T > >
116 static const array< T > add(
const array< T > &v1,
const array< T > &v2 )
118 array< T > ret( v1.size( ) );
119 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
121 ret[ i ] = v1[ i ] + v2[ i ];
126 static const array< T > add(
const array< T > &v1,
const typename array< T >::value_type &val )
128 array< T > ret( v1.size( ) );
129 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
131 ret[ i ] = v1[ i ] + val;
136 static const array< T > sub(
const array< T > &v1,
const array< T > &v2 )
138 array< T > ret( v1.size( ) );
139 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
141 ret[ i ] = v1[ i ] - v2[ i ];
146 static const array< T > sub(
const array< T > &v1,
const typename array< T >::value_type &val )
148 array< T > ret( v1.size( ) );
149 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
151 ret[ i ] = v1[ i ] - val;
156 static const array< T > mul(
const array< T > &v1,
const array< T > &v2 )
158 array< T > ret( v1.size( ) );
159 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
161 ret[ i ] = v1[ i ] * v2[ i ];
166 static const array< T > mul(
const array< T > &v1,
const typename array< T >::value_type &val )
168 array< T > ret( v1.size( ) );
169 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
171 ret[ i ] = v1[ i ] * val;
176 static const array< T > div(
const array< T > &v1,
const array< T > &v2 )
178 array< T > ret( v1.size( ) );
179 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
181 ret[ i ] = v1[ i ] / v2[ i ];
186 static const array< T > div(
const array< T > &v1,
const typename array< T >::value_type &val )
188 array< T > ret( v1.size( ) );
189 for(
size_t i = 0 ; i < ret.size( ) ; i ++ )
191 ret[ i ] = v1[ i ] / val;
199 template <
class T1,
class T2 >
200 inline const T1 add(
const T1 &v1,
const T2 &v2 ){
return( arithmetic_operation< T1 >::add( v1, v2 ) ); }
202 template <
class T1,
class T2 >
203 inline const T1 sub(
const T1 &v1,
const T2 &v2 ){
return( arithmetic_operation< T1 >::sub( v1, v2 ) ); }
205 template <
class T1,
class T2 >
206 inline const T1 div(
const T1 &v1,
const T2 &v2 ){
return( arithmetic_operation< T1 >::div( v1, v2 ) ); }
208 template <
class T1,
class T2 >
209 inline const T1 mul(
const T1 &v1,
const T2 &v2 ){
return( arithmetic_operation< T1 >::mul( v1, v2 ) ); }
264 template <
class T,
class Allocator = std::allocator< T > >
265 class spline :
public std::vector< T, Allocator >
268 typedef std::vector< T, Allocator > base;
269 typedef typename base::allocator_type allocator_type;
270 typedef typename base::reference reference;
271 typedef typename base::const_reference const_reference;
272 typedef typename base::value_type value_type;
273 typedef typename base::size_type size_type;
274 typedef typename base::difference_type difference_type;
275 typedef typename base::pointer pointer;
276 typedef typename base::const_pointer const_pointer;
278 typedef std::vector< value_type > point_list;
293 void closed_spline( )
295 using namespace __spline_utility__;
299 p.push_back( p[ 0 ] );
301 difference_type n, num = p.size( );
303 value_type *a =
new value_type[ num ];
304 value_type *b =
new value_type[ num ];
305 value_type *c =
new value_type[ num ];
308 value_type _0 = mul( value_type( base::operator[]( 0 ) ), 0 );
309 value_type _1 = add( _0, 1 );
310 value_type _2 = add( _0, 2 );
311 value_type _4 = add( _0, 4 );
319 p1_.push_back( mul( sub( p[ 1 ], p[ num - 2 ] ), 3 ) );
322 for( n = 1 ; n < num - 1 ; n++ )
327 p1_.push_back( mul( sub( p[ n + 1 ], p[ n - 1 ] ), 3 ) );
333 p1_.push_back( p1_[ 0 ] );
336 for( n = 1; n < num - 1; n++ )
338 a[ n ] = div( a[ n ], b[ n - 1 ] );
339 b[ n ] = sub( b[ n ], mul( a[ n ], c[ n - 1 ] ) );
340 p1_[ n ] = sub( p1_[ n ], mul( a[ n ], p1_[ n - 1 ] ) );
341 a[ n ] = mul( mul( a[ n - 1 ], a[ n ] ), -1 );
344 a[ num - 2 ] = mul( div( c[ num - 2 ], add( a[ num - 2 ], b[ num - 2 ] ) ), -1 );
345 b[ num - 2 ] = mul( mul( a[ num - 2 ], div( p1_[ num - 2 ], c[ num - 2 ] ) ), -1 );
347 value_type tmp( a[ num - 3 ] );
348 a[ num - 3 ] = mul( div( mul( add( a[ num - 3 ], c[ num - 3 ] ), a[ num - 2 ] ), b[ num - 3 ] ), -1 );
349 b[ num - 3 ] = div( sub( p1_[ num - 3 ], mul( add( tmp, c[ num - 2 ] ), b[ num - 2 ] ) ), b[ num - 3 ] );
351 for( n = num - 4 ; n >= 0 ; n-- )
353 value_type tmp( a[ n ] );
354 a[ n ] = div( mul( add( mul( c[ n ], a[ n + 1 ] ), mul( a[ n ], a[ num - 2 ] ) ), -1 ), b[ n ] );
355 b[ n ] = div( sub( sub( p1_[ n ], mul( c[ n ], b[ n + 1 ] ) ), mul( tmp, b[ num - 2 ] ) ), b[ n ] );
358 p1_[ 0 ] = div( b[ 0 ], add( a[ 0 ], 1 ) );
360 for( n = 1 ; n < num - 1 ; n++ )
362 p1_[ n ] = add( mul( a[ n ], p1_[ 0 ] ), b[ n ] );
375 using namespace __spline_utility__;
377 const base &p = *
this;
379 difference_type n, num = p.size( );
381 value_type *a =
new value_type[ num ];
382 value_type *b =
new value_type[ num ];
383 value_type *c =
new value_type[ num ];
388 value_type _0 = mul( value_type( base::operator[]( 0 ) ), 0 );
389 value_type _1 = add( _0, 1 );
390 value_type _2 = add( _0, 2 );
391 value_type _4 = add( _0, 4 );
397 p1_.push_back( mul( sub( p[ 1 ], p[ 0 ] ), 3 ) );
400 for( n = 1 ; n < num - 1 ; n++ )
405 p1_.push_back( mul( sub( p[ n + 1 ], p[ n - 1 ] ), 3 ) );
411 p1_.push_back( mul( sub( p[ num-1 ], p[ num-2 ] ), 3 ) );
414 for( n = 1; n < num; n++ )
416 a[ n ] = div( a[ n ], b[ n - 1 ] );
417 b[ n ] = sub( b[ n ], mul( a[ n ], c[ n - 1 ] ) );
418 p1_[ n ] = sub( p1_[ n ], mul( a[ n ], p1_[ n - 1 ] ) );
421 p1_[ num-1 ] = div( p1_[ num-1 ], b[ num-1 ] );
423 for( n = num-2; n >= 0; n-- )
425 p1_[ n ] = div( sub( p1_[n], mul( c[n], p1_[ n+1 ] ) ), b[n] );
435 void construct_spline( )
456 value_type operator( )(
double t )
458 using namespace __spline_utility__;
461 if( base::size( ) < 3 || p1_.size( ) < base::size( ) )
463 return( base::empty( ) ? value_type( 0 ) : base::at( 0 ) );
485 num = p1_.size( ) - 1;
489 size_type n =
static_cast< size_type
>( t *
static_cast< double >( num ) );
490 double step = 1.0 /
static_cast< double >( num );
492 value_type a0, a1, a2, a3;
493 const base &p = *
this;
500 a3 = add( mul( sub( p[ num - 1 ], p[ 0 ] ), 2 ), add( p1_[ num - 1 ], p1_[ 0 ] ) );
501 a2 = sub( add( mul( sub( p[ num - 1 ], p[ 0 ] ), -3 ), mul( p1_[ num - 1 ], -2 ) ), p1_[ 0 ] );
511 a3 = add( mul( sub( p[ n ], p[ n + 1 ] ), 2 ), add( p1_[ n ], p1_[ n + 1 ] ) );
512 a2 = sub( add( mul( sub( p[ n ], p[ n + 1 ] ), -3 ), mul( p1_[ n ], -2 ) ), p1_[ n + 1 ] );
526 a3 = add( mul( sub( p[ n ], p[ n + 1 ] ), 2 ), add( p1_[ n ], p1_[ n + 1 ] ) );
527 a2 = sub( add( mul( sub( p[ n ], p[ n + 1 ] ), -3 ), mul( p1_[ n ], -2 ) ), p1_[ n + 1 ] );
535 double s1 = t / step -
static_cast< double >( n );
539 return( add( add( add( mul( a3, s3 ), mul( a2, s2 ) ), mul( a1, s1 ) ), a0 ) );
555 base::operator =( b );
563 spline(
const spline &b ) : base( b ), mode_( b.mode_ ), p1_( b.p1_ ){ }
584 #endif // __INCLUDE_SPLINE__