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