1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkVector_h
19 #define itkVector_h
20 
21 #include "itkFixedArray.h"
22 
23 #include "vnl/vnl_vector_ref.h" // GetVnlVector method return
24 
25 namespace itk
26 {
27 /** \class Vector
28  * \brief A templated class holding a n-Dimensional vector.
29  *
30  * Vector is a templated class that holds a single vector (i.e., an array
31  * of values).  Vector can be used as the data type held at each pixel in
32  * an Image or at each vertex of an Mesh. The template parameter T can
33  * be any data type that behaves like a primitive (or atomic) data type (int,
34  * short, float, complex).  The NVectorDimension defines the number of
35  * components in the vector array.
36  *
37  * Vector is not a dynamically extendible array like std::vector. It is
38  * intended to be used like a mathematical vector.
39  *
40  * If you wish a simpler pixel types, you can use Scalar, which represents
41  * a single data value at a pixel. There is also the more complex type
42  * ScalarVector, which supports (for a given pixel) a single scalar value
43  * plus an array of vector values. (The scalar and vectors can be of
44  * different data type.)
45  *
46  * \ingroup Geometry
47  * \ingroup DataRepresentation
48  *
49  * \sa Image
50  * \sa Mesh
51  * \sa Point
52  * \sa CovariantVector
53  * \sa Matrix
54  * \ingroup ITKCommon
55  *
56  * \wiki
57  * \wikiexample{SimpleOperations/CreateVector,Create a vector}
58  * \wikiexample{Math/DotProduct,Dot product (inner product) of two vectors}
59  * \endwiki
60  */
61 template< typename T, unsigned int NVectorDimension = 3 >
62 class ITK_TEMPLATE_EXPORT Vector:public FixedArray< T, NVectorDimension >
63 {
64 public:
65   /** Standard class type aliases. */
66   using Self = Vector;
67   using Superclass = FixedArray< T, NVectorDimension >;
68 
69   /** ValueType can be used to declare a variable that is the same type
70    * as a data element held in an Vector.   */
71   using ValueType = T;
72   using RealValueType = typename NumericTraits< ValueType >::RealType;
73 
74   /** Dimension of the vector space. */
75   static constexpr unsigned int Dimension = NVectorDimension;
76 
77   /** I am a vector type. */
78   using VectorType = Self;
79 
80   /** Component value type */
81   using ComponentType = T;
82 
83   /** The Array type from which this vector is derived. */
84   using BaseArray = FixedArray< T, NVectorDimension >;
85 
86   /** Get the dimension (size) of the vector. */
GetVectorDimension()87   static unsigned int GetVectorDimension() { return NVectorDimension; }
88 
89   /** Set a vnl_vector_ref referencing the same memory block. */
90   void SetVnlVector(const vnl_vector< T > &);
91 
92   /** Get a vnl_vector_ref referencing the same memory block. */
93   vnl_vector_ref< T > GetVnlVector();
94 
95   /** Get a vnl_vector with a copy of the internal memory block. */
96   vnl_vector< T > GetVnlVector() const;
97 
98   /** Default constructors, assignments and destructor */
99   Vector() = default;
100   Vector(const Vector&) = default;
101   Vector(Vector&&) = default;
102   Vector & operator=(const Vector &) = default;
103   Vector & operator=(Vector &&) = default;
104   ~Vector() = default;
105 
106 #if !defined( ITK_LEGACY_FUTURE_REMOVE )
107   /** Constructor to initialize entire vector to one value.
108    * \warning Not intended to convert a scalar value into
109    * a Vector filled with that value.
110    * \deprecated */
111   Vector(const ValueType & r);
112 #else
113   /** Constructor to initialize entire vector to one value,
114    * if explicitly invoked. */
115   explicit Vector(const ValueType & r);
116 #endif
117 
118   /** Pass-through constructor for the Array base class. */
119   template< typename TVectorValueType >
Vector(const Vector<TVectorValueType,NVectorDimension> & r)120   Vector(const Vector< TVectorValueType, NVectorDimension > & r):BaseArray(r) {}
Vector(const ValueType r[Dimension])121   Vector(const ValueType r[Dimension]):BaseArray(r) {}
122 
123   /** Pass-through assignment operator for the Array base class. */
124   template< typename TVectorValueType >
125   Vector & operator=(const Vector< TVectorValueType, NVectorDimension > & r)
126   {
127     BaseArray::operator=(r);
128     return *this;
129   }
130 
131   Vector & operator=(const ValueType r[NVectorDimension]);
132 
133   /** Scalar operator*=.  Scales elements by a scalar. */
134   template< typename Tt >
135   inline const Self & operator*=(const Tt & value)
136   {
137     for ( unsigned int i = 0; i < NVectorDimension; i++ )
138       {
139       ( *this )[i] = static_cast< ValueType >( ( *this )[i] * value );
140       }
141     return *this;
142   }
143 
144   /** Scalar operator/=.  Scales (divides) elements by a scalar. */
145   template< typename Tt >
146   inline const Self & operator/=(const Tt & value)
147   {
148     for ( unsigned int i = 0; i < NVectorDimension; i++ )
149       {
150       ( *this )[i] = static_cast< ValueType >( ( *this )[i] / value );
151       }
152     return *this;
153   }
154 
155   /** Vector operator+=.  Adds a vectors to the current vector. */
156   const Self & operator+=(const Self & vec);
157 
158   /** Vector operator-=.  Subtracts a vector from a current vector. */
159   const Self & operator-=(const Self & vec);
160 
161   /** Vector negation.  Negate all the elements of a vector. Return a new
162    *  vector */
163   Self operator-() const;
164 
165   /** Vector addition. Add two vectors. Return a new vector. */
166   Self operator+(const Self & vec) const;
167 
168   /** Vector subtraction. Subtract two vectors. Return a new vector. */
169   Self operator-(const Self & vec) const;
170 
171   /** Vector operator*.  Performs the inner product of two vectors.
172    * this is also known as the scalar product. */
173   ValueType operator *(const Self & vec) const;
174 
175   /** Scalar operator*. Scale the elements of a vector by a scalar.
176    * Return a new vector. */
177   inline Self operator*(const ValueType & value) const
178   {
179     Self result;
180 
181     for ( unsigned int i = 0; i < NVectorDimension; i++ )
182       {
183       result[i] = static_cast< ValueType >( ( *this )[i] * value );
184       }
185     return result;
186   }
187 
188   /** Scalar operator/. Scale (divide) the elements of a vector by a scalar.
189    * Return a new vector. */
190   template< typename Tt >
191   inline Self operator/(const Tt & value) const
192   {
193     Self result;
194 
195     for ( unsigned int i = 0; i < NVectorDimension; i++ )
196       {
197       result[i] = static_cast< ValueType >( ( *this )[i] / value );
198       }
199     return result;
200   }
201 
202   /** Operators == and != compare a vector component by component. All
203    * components must be equal for two vectors to be equal. (Of course
204    * compile-time constraints on the template parameters length and type
205    * prevent comparisons between vectors of different type and length.) */
206   bool operator==(const Self & v) const
207   { return Superclass::operator==(v); }
208   bool operator!=(const Self & v) const
209   { return !operator==(v); }
210 
211   /** Returns the Euclidean Norm of the vector  */
212   RealValueType GetNorm() const;
213 
214   /** Returns vector's Squared Euclidean Norm  */
215   RealValueType GetSquaredNorm() const;
216 
217   /** Returns the number of components in this vector type */
GetNumberOfComponents()218   static unsigned int GetNumberOfComponents() { return NVectorDimension; }
219 
220   /** Divides the vector components by the vector norm (when the norm is not
221     * null). The norm used is returned. */
222   RealValueType Normalize();
223 
SetNthComponent(int c,const ComponentType & v)224   void SetNthComponent(int c, const ComponentType & v)
225   {  this->operator[](c) = v; }
226 
227   /** Copy from another Vector with a different representation type.
228    *  Casting is done with C-Like rules  */
229   template< typename TCoordRepB >
CastFrom(const Vector<TCoordRepB,NVectorDimension> & pa)230   void CastFrom(const Vector< TCoordRepB, NVectorDimension > & pa)
231   {
232     for ( unsigned int i = 0; i < NVectorDimension; i++ )
233       {
234       ( *this )[i] = static_cast< T >( pa[i] );
235       }
236   }
237 
238   template<typename TCoordRepB>
239   operator Vector< TCoordRepB, NVectorDimension >()
240   {
241     Vector<TCoordRepB, NVectorDimension> r;
242     for (unsigned int i = 0; i < NVectorDimension; i++)
243     {
244       r[i] = static_cast<TCoordRepB> ((*this)[i]);
245     }
246     return r;
247   }
248 
249 };
250 
251 /** Premultiply Operator for product of a vector and a scalar.
252  *  Vector< T, N >  =  T * Vector< T,N > */
253 template< typename T, unsigned int NVectorDimension >
254 inline
255 Vector< T, NVectorDimension >
256 operator*(const T & scalar, const Vector< T, NVectorDimension > & v)
257 {
258   return v.operator*( scalar);
259 }
260 
261 /** Print content to an ostream */
262 template< typename T, unsigned int NVectorDimension >
263 std::ostream & operator<<(std::ostream & os,
264                           const Vector< T, NVectorDimension > & v);
265 
266 /** Read content from an istream */
267 template< typename T, unsigned int NVectorDimension >
268 std::istream & operator>>(std::istream & is,
269                           Vector< T, NVectorDimension > & v);
270 
271 ITKCommon_EXPORT Vector< double, 3 > CrossProduct(const Vector< double, 3 > &,
272                                                   const Vector< double, 3 > &);
273 
274 ITKCommon_EXPORT Vector< float, 3 > CrossProduct(const Vector< float, 3 > &,
275                                                  const Vector< float, 3 > &);
276 
277 ITKCommon_EXPORT Vector< int, 3 > CrossProduct(const Vector< int, 3 > &,
278                                                const Vector< int, 3 > &);
279 
280 
281 template< typename T, unsigned int NVectorDimension >
swap(Vector<T,NVectorDimension> & a,Vector<T,NVectorDimension> & b)282 inline void swap( Vector<T, NVectorDimension> &a, Vector<T, NVectorDimension> &b )
283 {
284   a.swap(b);
285 }
286 
287 } // end namespace itk
288 
289 #ifndef ITK_MANUAL_INSTANTIATION
290 #include "itkVector.hxx"
291 #endif
292 
293 #endif
294