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

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

vector.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 #ifndef __INCLUDE_MIST_VECTOR__
34 #define __INCLUDE_MIST_VECTOR__
35
36
37 #ifndef __INCLUDE_MIST_CONF_H__
38 #include "config/mist_conf.h"
39 #endif
40
41 #ifndef __INCLUDE_MIST_TYPE_TRAIT_H__
42 #include "config/type_trait.h"
43 #endif
44
45 #include <cmath>
46
47 // mist名前空間の始まり
48 _MIST_BEGIN
49
50
58
59
60
67 template < class T >
68 class vector3
69 {
70 public:
71 typedef T value_type;
72 typedef size_t size_type;
73 typedef ptrdiff_t difference_type;
74 typedef typename float_type< T >::value_type float_type;
75
76 public:
77 value_type x;
78 value_type y;
79 value_type z;
80
82 vector3( ) : x( 0 ), y( 0 ), z( 0 ){ }
83
85 vector3( const value_type &xx, const value_type &yy, const value_type &zz ) : x( xx ), y( yy ), z( zz ){ }
86
88 explicit vector3( const value_type &vv ) : x( vv ), y( vv ), z( vv ){ }
89
90
95 template < class TT >
96 vector3( const vector3< TT > &v ) : x( static_cast< value_type >( v.x ) ), y( static_cast< value_type >( v.y ) ), z( static_cast< value_type >( v.z ) ){ }
97
98
100 vector3( const vector3< T > &v ) : x( v.x ), y( v.y ), z( v.z ){ }
101
102
111 template < class TT >
112 const vector3 &operator =( const vector3< TT > &v )
113 {
114 x = static_cast< value_type >( v.x );
115 y = static_cast< value_type >( v.y );
116 z = static_cast< value_type >( v.z );
117 return ( *this );
118 }
119
128 const vector3 &operator =( const vector3< T > &v )
129 {
130 if( &v != this )
131 {
132 x = v.x;
133 y = v.y;
134 z = v.z;
135 }
136 return ( *this );
137 }
138
139
141 vector3 operator -( ) const { return ( vector3( -x, -y, -z ) ); }
142
143
145 template < class TT >
146 vector3 &operator +=( const vector3< TT > &v )
147 {
148 x = static_cast< value_type >( x + v.x );
149 y = static_cast< value_type >( y + v.y );
150 z = static_cast< value_type >( z + v.z );
151 return( *this );
152 }
153
155 template < class TT >
156 vector3 &operator -=( const vector3< TT > &v )
157 {
158 x = static_cast< value_type >( x - v.x );
159 y = static_cast< value_type >( y - v.y );
160 z = static_cast< value_type >( z - v.z );
161 return( *this );
162 }
163
165 template < class TT >
166 vector3 &operator *=( const vector3< TT > &v )
167 {
168 value_type xx = static_cast< value_type >( y * v.z - z * v.y );
169 value_type yy = static_cast< value_type >( z * v.x - x * v.z );
170 value_type zz = static_cast< value_type >( x * v.y - y * v.x );
171 x = xx;
172 y = yy;
173 z = zz;
174 return( *this );
175 }
176
178 #if defined( __MIST_MSVC__ ) && __MIST_MSVC__ < 7
179 vector3 &operator *=( const double &a )
180 #else
181 template < class TT >
182 vector3 &operator *=( const TT &a )
183 #endif
184 {
185 x = static_cast< value_type >( x * a );
186 y = static_cast< value_type >( y * a );
187 z = static_cast< value_type >( z * a );
188 return( *this );
189 }
190
191
193 #if defined( __MIST_MSVC__ ) && __MIST_MSVC__ < 7
194 vector3 &operator /=( const double &a )
195 #else
196 template < class TT >
197 vector3 &operator /=( const TT &a )
198 #endif
199 {
200 x = static_cast< value_type >( x / a );
201 y = static_cast< value_type >( y / a );
202 z = static_cast< value_type >( z / a );
203 return( *this );
204 }
205
206
216 bool operator ==( const vector3 &v ) const { return( x == v.x && y == v.y && z == v.z ); }
217
227 bool operator !=( const vector3 &v ) const { return( !( *this == v ) ); }
228
238 bool operator < ( const vector3 &v ) const
239 {
240 if( x == v.x )
241 {
242 if( y == v.y )
243 {
244 return( z < v.z );
245 }
246 else
247 {
248 return( y < v.y );
249 }
250 }
251 else
252 {
253 return( x < v.x );
254 }
255 }
256
266 bool operator <=( const vector3 &v ) const { return( v >= *this ); }
267
277 bool operator > ( const vector3 &v ) const { return( v < *this ); }
278
288 bool operator >=( const vector3 &v ) const { return( !( *this < v ) ); }
289
290
295 vector3 unit( ) const
296 {
297 float_type length_ = length( );
298 if( length_ > 0 )
299 {
300 return( vector3( static_cast< value_type >( x / length_ ), static_cast< value_type >( y / length_ ), static_cast< value_type >( z / length_ ) ) );
301 }
302 else
303 {
304 return( *this );
305 }
306 }
307
308
315 template < class TT >
316 typename promote_trait< T, TT >::value_type inner( const vector3< TT > &v ) const
317 {
318 return( static_cast< typename promote_trait< T, TT >::value_type >( x * v.x + y * v.y + z * v.z ) );
319 }
320
321
328 template < class TT >
329 vector3< typename promote_trait< value_type, TT >::value_type > outer( const vector3< TT > &v ) const
330 {
331 return( vector3< typename promote_trait< value_type, TT >::value_type >( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ) );
332 }
333
334
341 float_type length( ) const { return ( static_cast< float_type >( std::sqrt( static_cast< double >( x * x + y * y + z * z ) ) ) ); }
342
350 vector3 rotate( const vector3 &v, double theta ) const
351 {
352 theta *= 3.1415926535897932384626433832795 / 180.0;
353 double cs = std::cos( theta ), sn = std::sin( theta );
354 value_type xx = static_cast< value_type >( ( v.x * v.x * ( 1.0 - cs ) + cs ) * x + ( v.x * v.y * ( 1.0 - cs ) - v.z * sn ) * y + ( v.x * v.z * ( 1.0 - cs ) + v.y * sn ) * z );
355 value_type yy = static_cast< value_type >( ( v.x * v.y * ( 1.0 - cs ) + v.z * sn ) * x + ( v.y * v.y * ( 1.0 - cs ) + cs ) * y + ( v.y * v.z * ( 1.0 - cs ) - v.x * sn ) * z );
356 value_type zz = static_cast< value_type >( ( v.x * v.z * ( 1.0 - cs ) - v.y * sn ) * x + ( v.y * v.z * ( 1.0 - cs ) + v.x * sn ) * y + ( v.z * v.z * ( 1.0 - cs ) + cs ) * z );
357 return ( vector3( xx, yy, zz ) );
358 }
359 };
360
361
363 template < class T1, class T2 >
364 inline typename promote_trait< T1, T2 >::value_type operator ^( const vector3< T1 > &v1, const vector3< T2 > &v2 )
365 {
366 typedef typename promote_trait< T1, T2 >::value_type value_type;
367 return( vector3< value_type >( v1 ).inner( v2 ) );
368 }
369
370 // 型の昇格を行う演算の定義
371
373 DEFINE_PROMOTE_BIND_OPERATOR1( vector3, + )
374
375
376 DEFINE_PROMOTE_BIND_OPERATOR1( vector3, - )
377
379 DEFINE_PROMOTE_BIND_OPERATOR1( vector3, * )
380
382 DEFINE_PROMOTE_BIND_OPERATOR2( vector3, * )
383
385 DEFINE_PROMOTE_BIND_OPERATOR3( vector3, * )
386
388 DEFINE_PROMOTE_BIND_OPERATOR2( vector3, / )
389
390
391
403 template < class T > inline std::ostream &operator <<( std::ostream &out, const vector3< T > &v )
404 {
405 out << v.x << ", ";
406 out << v.y << ", ";
407 out << v.z;
408 return( out );
409 }
410
422 template < class T > inline std::istream &operator >>( std::istream &in, vector3< T > &v )
423 {
424 std::string comma;
425 in >> v.x >> comma;
426 in >> v.y >> comma;
427 in >> v.z;
428 return( in );
429 }
430
431
432
439 template < class T >
440 class vector2
441 {
442 public:
443 typedef T value_type;
444 typedef size_t size_type;
445 typedef ptrdiff_t difference_type;
446 typedef typename float_type< T >::value_type float_type;
447
448 public:
449 value_type x;
450 value_type y;
451
453 vector2( ) : x( 0 ), y( 0 ){ }
454
456 vector2( const value_type &xx, const value_type &yy ) : x( xx ), y( yy ){ }
457
459 explicit vector2( const value_type &vv ) : x( vv ), y( vv ){ }
460
461
466 template < class TT >
467 vector2( const vector2< TT > &v ) : x( static_cast< value_type >( v.x ) ), y( static_cast< value_type >( v.y ) ){ }
468
469
471 vector2( const vector2< T > &v ) : x( v.x ), y( v.y ){ }
472
473
482 template < class TT >
483 const vector2 &operator =( const vector2< TT > &v )
484 {
485 x = static_cast< value_type >( v.x );
486 y = static_cast< value_type >( v.y );
487 return ( *this );
488 }
489
498 const vector2 &operator =( const vector2< T > &v )
499 {
500 if( &v != this )
501 {
502 x = v.x;
503 y = v.y;
504 }
505 return ( *this );
506 }
507
508
510 vector2 operator -( ) const { return ( vector2( -x, -y ) ); }
511
512
514 template < class TT >
515 vector2 &operator +=( const vector2< TT > &v ){ x = static_cast< value_type >( x + v.x ); y = static_cast< value_type >( y + v.y ); return( *this ); }
516
518 template < class TT >
519 vector2 &operator -=( const vector2< TT > &v ){ x = static_cast< value_type >( x - v.x ); y = static_cast< value_type >( y - v.y ); return( *this ); }
520
521
523 #if defined( __MIST_MSVC__ ) && __MIST_MSVC__ < 7
524 vector2 &operator *=( const double &a )
525 #else
526 template < class TT >
527 vector2 &operator *=( const TT &a )
528 #endif
529 {
530 x = static_cast< value_type >( x * a );
531 y = static_cast< value_type >( y * a );
532 return( *this );
533 }
534
535
537 #if defined( __MIST_MSVC__ ) && __MIST_MSVC__ < 7
538 vector2 &operator /=( const double &a )
539 #else
540 template < class TT >
541 vector2 &operator /=( const TT &a )
542 #endif
543 {
544 x = static_cast< value_type >( x / a );
545 y = static_cast< value_type >( y / a );
546 return( *this );
547 }
548
549
559 bool operator ==( const vector2 &v ) const { return( x == v.x && y == v.y ); }
560
570 bool operator !=( const vector2 &v ) const { return( !( *this == v ) ); }
571
581 bool operator < ( const vector2 &v ) const
582 {
583 if( x == v.x )
584 {
585 return( y < v.y );
586 }
587 else
588 {
589 return( x < v.x );
590 }
591 }
592
602 bool operator <=( const vector2 &v ) const { return( v >= *this ); }
603
613 bool operator > ( const vector2 &v ) const { return( v < *this ); }
614
624 bool operator >=( const vector2 &v ) const { return( !( *this < v ) ); }
625
626
631 vector2 unit( ) const
632 {
633 float_type length_ = length( );
634 if( length_ > 0 )
635 {
636 return( vector2( static_cast< value_type >( x / length_ ), static_cast< value_type >( y / length_ ) ) );
637 }
638 else
639 {
640 return( *this );
641 }
642 }
643
644
651 template < class TT >
652 typename promote_trait< T, TT >::value_type inner( const vector2< TT > &v ) const { return( static_cast< typename promote_trait< T, TT >::value_type >( x * v.x + y * v.y ) ); }
653
654
661 template < class TT >
662 typename promote_trait< T, TT >::value_type outer( const vector2< TT > &v ) const { return( static_cast< typename promote_trait< T, TT >::value_type >( x * v.y - y * v.x ) ); }
663
664
671 float_type length( ) const { return ( static_cast< float_type >( std::sqrt( static_cast< double >( x * x + y * y ) ) ) ); }
672
674 //vector2 rotate( const vector2 &a, double theta ) const
675 //{
676 // theta *= 3.1415926535897932384626433832795 / 180.0;
677 // double cs = std::cos( theta ), sn = std::sin( theta );
678 // value_type xx = static_cast< value_type >( ( v.x * v.x * ( 1.0 - cs ) + cs ) * x + ( v.x * v.y * ( 1.0 - cs ) - v.z * sn ) * y + ( v.x * v.z * ( 1.0 - cs ) + v.y * sn ) * z );
679 // value_type yy = static_cast< value_type >( ( v.x * v.y * ( 1.0 - cs ) + v.z * sn ) * x + ( v.y * v.y * ( 1.0 - cs ) + cs ) * y + ( v.y * v.z * ( 1.0 - cs ) - v.x * sn ) * z );
680 // value_type zz = static_cast< value_type >( ( v.x * v.z * ( 1.0 - cs ) - v.y * sn ) * x + ( v.y * v.z * ( 1.0 - cs ) + v.x * sn ) * y + ( v.z * v.z * ( 1.0 - cs ) + cs ) * z );
681 // return ( vector2( xx, yy, zz ) );
682 //}
683
684 };
685
686
688 template < class T1, class T2 >
689 inline typename promote_trait< T1, T2 >::value_type operator ^( const vector2< T1 > &v1, const vector2< T2 > &v2 )
690 {
691 typedef typename promote_trait< T1, T2 >::value_type value_type;
692 return( vector2< value_type >( v1 ).inner( v2 ) );
693 }
694
696 template < class T1, class T2 >
697 inline typename promote_trait< T1, T2 >::value_type operator *( const vector2< T1 > &v1, const vector2< T2 > &v2 )
698 {
699 typedef typename promote_trait< T1, T2 >::value_type value_type;
700 return( vector2< value_type >( v1 ).outer( v2 ) );
701 }
702
703
704 // 型の昇格を行う演算の定義
706 DEFINE_PROMOTE_BIND_OPERATOR1( vector2, + )
707
708
709 DEFINE_PROMOTE_BIND_OPERATOR1( vector2, - )
710
712 DEFINE_PROMOTE_BIND_OPERATOR2( vector2, * )
713
715 DEFINE_PROMOTE_BIND_OPERATOR3( vector2, * )
716
718 DEFINE_PROMOTE_BIND_OPERATOR2( vector2, / )
719
720
732 template < class T > inline std::ostream &operator <<( std::ostream &out, const vector2< T > &v )
733 {
734 out << v.x << ", ";
735 out << v.y;
736 return( out );
737 }
738
750 template < class T > inline std::istream &operator >>( std::istream &in, vector2< T > &v )
751 {
752 std::string comma;
753 in >> v.x >> comma;
754 in >> v.y;
755 return( in );
756 }
757
758
759
760 #if defined( _MIST_VECTOR_SUPPORT_ ) && _MIST_VECTOR_SUPPORT_ != 0
761
762
772 template < class T, class Allocator = ::std::allocator< T > >
773 class vector : public matrix< T, Allocator >
774 {
775 private:
776 typedef matrix< T, Allocator > base;
777
778 public:
779 typedef typename base::allocator_type allocator_type;
780 typedef typename base::reference reference;
781 typedef typename base::const_reference const_reference;
782 typedef typename base::value_type value_type;
783 typedef typename base::size_type size_type;
784 typedef typename base::difference_type difference_type;
785 typedef typename base::pointer pointer;
786 typedef typename base::const_pointer const_pointer;
787
788 typedef typename base::iterator iterator;
789 typedef typename base::const_iterator const_iterator;
790 typedef typename base::reverse_iterator reverse_iterator;
791 typedef typename base::const_reverse_iterator const_reverse_iterator;
792
794 template < class TT, class AAllocator = std::allocator< TT > >
795 struct rebind
796 {
797 typedef vector< TT, AAllocator > other;
798 };
799
800
801 //template < class TT, class AAlocator >
802 //const vector& operator +=( const vector< TT, AAlocator > &v2 )
803 //{
804 // base::operator +=( v2 );
805 // return( v1 );
806 //}
807
808 //template < class TT, class AAlocator >
809 //const vector& operator -=( const vector< TT, AAlocator > &v2 )
810 //{
811 // base::operator -=( v2 );
812 // return( v1 );
813 //}
814
815
824 template < class TT, class AAlocator >
825 const vector& operator *=( const vector< TT, AAlocator > &v2 )
826 {
827 #if defined( _CHECK_MATRIX_OPERATION_ ) && _CHECK_MATRIX_OPERATION_ != 0
828 if( base::size( ) != v2.size( ) || base::size( ) < 3 )
829 {
830 // 外積の計算ができません例外
831 ::std::cerr << "can't calculate outer product of two vectors." << ::std::endl;
832 return( *this );
833 }
834 #endif
835
836 typedef typename vector< T, Allocator >::size_type size_type;
837 vector &v1 = *this;
838 vector v( v1.size( ) );
839
840 size_type i;
841 for( i = 0 ; i < v.size( ) - 2 ; i++ )
842 {
843 v[ i ] = v1[ i + 1 ] * v2[ i + 2 ] - v1[ i + 2 ] * v2[ i + 1 ];
844 }
845
846 v[ i ] = v1[ i + 1 ] * v2[ 0 ] - v1[ 0 ] * v2[ i + 1 ];
847 v[ i + 1 ] = v1[ 0 ] * v2[ 1 ] - v1[ 1 ] * v2[ 0 ];
848
849 v1.swap( v );
850
851 return( *this );
852 }
853
854
863 value_type operator ^( const vector &v ) const { return( inner( v ) ); }
864
865
874 value_type inner( const vector &v2 ) const
875 {
876 #if defined( _CHECK_MATRIX_OPERATION_ ) && _CHECK_MATRIX_OPERATION_ != 0
877 if( base::size( ) != v2.size( ) )
878 {
879 // 内積の計算ができません例外
880 ::std::cerr << "can't calculate inner product of two vectors." << ::std::endl;
881 return( value_type( 0 ) );
882 }
883 #endif
884
885 typedef typename vector< T, Allocator >::size_type size_type;
886 const vector &v1 = *this;
887 value_type v = value_type( 0 );
888 for( size_type i = 0 ; i < base::size( ) ; i++ )
889 {
890 v += v1[ i ] * v2[ i ];
891 }
892
893 return( v );
894 }
895
896
905 vector outer( const vector &v ) const
906 {
907 return( vector( *this ) *= v );
908 }
909
910
911 public:
913 vector( ) : base( ) {}
914
916 explicit vector( const Allocator &a ) : base( a ) {}
917
918
920 vector( size_type num ) : base( num, 1 ) {}
921
923 vector( size_type num, const Allocator &a ) : base( num, 1, a ) {}
924
925
927 vector( size_type num, const T &val ) : base( num, 1, val ) {}
928
930 vector( size_type num, const T &val, const Allocator &a ) : base( num, 1, val, a ) {}
931
932
934 vector( size_type num, pointer ptr, size_type mem_available ) : base( num, 1, ptr, mem_available ) {}
935
937 vector( size_type num, const T &val, pointer ptr, size_type mem_available ) : base( num, 1, val, ptr, mem_available ) {}
938
939
944 template < class TT, class AAlocator >
945 vector( const vector< TT, AAlocator > &o ) : base( o ){ }
946
947
949 vector( const vector< T, Allocator > &o ) : base( o ){ }
950
951 #if _USE_EXPRESSION_TEMPLATE_ != 0
952
953 template < class Expression >
954 vector( const matrix_expression< Expression > &expression ) : base( expression.size( ), 1 )
955 {
956 vector &v = *this;
957 for( size_type indx = 0 ; indx < v.size( ) ; indx++ )
958 {
959 v[ indx ] = expression[ indx ];
960 }
961 }
962 #endif
963 };
964
965
966
978 template < class T, class Allocator >
979 inline ::std::ostream &operator <<( ::std::ostream &out, const vector< T, Allocator > &v )
980 {
981 typename vector< T, Allocator >::size_type indx;
982 for( indx = 0 ; indx < v.size( ) ; indx++ )
983 {
984 out << v[ indx ];
985 if( indx != v.size( ) - 1 ) out << ", ";
986 }
987
988 return( out );
989 }
990
991 #if 0
992 #else
993
1003 template < class T, class Allocator >
1004 inline vector< T, Allocator > operator *( const vector< T, Allocator > &v1, const vector< T, Allocator > &v2 )
1005 {
1006 return( vector< T, Allocator >( v1 ) *= v2 );
1007 }
1008
1009 #endif
1010
1011
1012
1013 #endif // _MIST_VECTOR_SUPPORT_
1014
1016 // ベクトルライブラリグループの終わり
1017
1018
1019 // mist名前空間の終わり
1020 _MIST_END
1021
1022 #endif // __INCLUDE_MIST_VECTOR__
1023