/*========================================================================= Program: Visualization Toolkit Module: vtkVector.h Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /** * @class vtkVector * @brief templated base type for storage of vectors. * * * This class is a templated data type for storing and manipulating fixed size * vectors, which can be used to represent two and three dimensional points. The * memory layout is a contiguous array of the specified type, such that a * float[2] can be cast to a vtkVector2f and manipulated. Also a float[6] could * be cast and used as a vtkVector2f[3]. */ #ifndef vtkVector_h #define vtkVector_h #include "vtkObject.h" // for legacy macros #include "vtkTuple.h" #include // For math functions template class vtkVector : public vtkTuple { public: vtkVector() {} /** * Initialize all of the vector's elements with the supplied scalar. */ explicit vtkVector(const T& scalar) : vtkTuple(scalar) { } /** * Initialize the vector's elements with the elements of the supplied array. * Note that the supplied pointer must contain at least as many elements as * the vector, or it will result in access to out of bounds memory. */ explicit vtkVector(const T* init) : vtkTuple(init) { } //@{ /** * Get the squared norm of the vector. */ T SquaredNorm() const { T result = 0; for (int i = 0; i < Size; ++i) { result += this->Data[i] * this->Data[i]; } return result; } //@} /** * Get the norm of the vector, i.e. its length. */ double Norm() const { return sqrt(static_cast(this->SquaredNorm())); } //@{ /** * Normalize the vector in place. * \return The length of the vector. */ double Normalize() { const double norm(this->Norm()); if (norm == 0.0) { return 0.0; } const double inv(1.0 / norm); for (int i = 0; i < Size; ++i) { this->Data[i] = static_cast(this->Data[i] * inv); } return norm; } //@} //@{ /** * Return the normalized form of this vector. * \return The normalized form of this vector. */ vtkVector Normalized() const { vtkVector temp(*this); temp.Normalize(); return temp; } //@} //@{ /** * The dot product of this and the supplied vector. */ T Dot(const vtkVector& other) const { T result(0); for (int i = 0; i < Size; ++i) { result += this->Data[i] * other[i]; } return result; } //@} //@{ /** * Cast the vector to the specified type, returning the result. */ template vtkVector Cast() const { vtkVector result; for (int i = 0; i < Size; ++i) { result[i] = static_cast(this->Data[i]); } return result; } //@} }; // .NAME vtkVector2 - templated base type for storage of 2D vectors. // template class vtkVector2 : public vtkVector { public: vtkVector2() {} explicit vtkVector2(const T& scalar) : vtkVector(scalar) { } explicit vtkVector2(const T* init) : vtkVector(init) { } vtkVector2(const T& x, const T& y) { this->Data[0] = x; this->Data[1] = y; } //@{ /** * Set the x and y components of the vector. */ void Set(const T& x, const T& y) { this->Data[0] = x; this->Data[1] = y; } //@} /** * Set the x component of the vector, i.e. element 0. */ void SetX(const T& x) { this->Data[0] = x; } /** * Get the x component of the vector, i.e. element 0. */ const T& GetX() const { return this->Data[0]; } /** * Set the y component of the vector, i.e. element 1. */ void SetY(const T& y) { this->Data[1] = y; } /** * Get the y component of the vector, i.e. element 1. */ const T& GetY() const { return this->Data[1]; } //@{ /** * Lexicographical comparison of two vector. */ bool operator<(const vtkVector2& v) const { return (this->Data[0] < v.Data[0]) || (this->Data[0] == v.Data[0] && this->Data[1] < v.Data[1]); } //@} }; // .NAME vtkVector3 - templated base type for storage of 3D vectors. // template class vtkVector3 : public vtkVector { public: vtkVector3() {} explicit vtkVector3(const T& scalar) : vtkVector(scalar) { } explicit vtkVector3(const T* init) : vtkVector(init) { } vtkVector3(const T& x, const T& y, const T& z) { this->Data[0] = x; this->Data[1] = y; this->Data[2] = z; } //@{ /** * Set the x, y and z components of the vector. */ void Set(const T& x, const T& y, const T& z) { this->Data[0] = x; this->Data[1] = y; this->Data[2] = z; } //@} /** * Set the x component of the vector, i.e. element 0. */ void SetX(const T& x) { this->Data[0] = x; } /** * Get the x component of the vector, i.e. element 0. */ const T& GetX() const { return this->Data[0]; } /** * Set the y component of the vector, i.e. element 1. */ void SetY(const T& y) { this->Data[1] = y; } /** * Get the y component of the vector, i.e. element 1. */ const T& GetY() const { return this->Data[1]; } /** * Set the z component of the vector, i.e. element 2. */ void SetZ(const T& z) { this->Data[2] = z; } /** * Get the z component of the vector, i.e. element 2. */ const T& GetZ() const { return this->Data[2]; } //@{ /** * Return the cross product of this X other. */ vtkVector3 Cross(const vtkVector3& other) const { vtkVector3 res; res[0] = this->Data[1] * other.Data[2] - this->Data[2] * other.Data[1]; res[1] = this->Data[2] * other.Data[0] - this->Data[0] * other.Data[2]; res[2] = this->Data[0] * other.Data[1] - this->Data[1] * other.Data[0]; return res; } //@} //@{ /** * Lexicographical comparison of two vector. */ bool operator<(const vtkVector3& v) const { return (this->Data[0] < v.Data[0]) || (this->Data[0] == v.Data[0] && this->Data[1] < v.Data[1]) || (this->Data[0] == v.Data[0] && this->Data[1] == v.Data[1] && this->Data[2] < v.Data[2]); } //@} }; // .NAME vtkVector4 - templated base type for storage of 4D vectors. // template class vtkVector4 : public vtkVector { public: vtkVector4() {} explicit vtkVector4(const T& scalar) : vtkVector(scalar) { } explicit vtkVector4(const T* init) : vtkVector(init) { } vtkVector4(const T& x, const T& y, const T& z, const T& w) { this->Data[0] = x; this->Data[1] = y; this->Data[2] = z; this->Data[3] = w; } //@{ /** * Set the x, y, z and w components of a 3D vector in homogeneous coordinates. */ void Set(const T& x, const T& y, const T& z, const T& w) { this->Data[0] = x; this->Data[1] = y; this->Data[2] = z; this->Data[3] = w; } //@} /** * Set the x component of the vector, i.e. element 0. */ void SetX(const T& x) { this->Data[0] = x; } /** * Get the x component of the vector, i.e. element 0. */ const T& GetX() const { return this->Data[0]; } /** * Set the y component of the vector, i.e. element 1. */ void SetY(const T& y) { this->Data[1] = y; } /** * Get the y component of the vector, i.e. element 1. */ const T& GetY() const { return this->Data[1]; } /** * Set the z component of the vector, i.e. element 2. */ void SetZ(const T& z) { this->Data[2] = z; } /** * Get the z component of the vector, i.e. element 2. */ const T& GetZ() const { return this->Data[2]; } /** * Set the w component of the vector, i.e. element 3. */ void SetW(const T& w) { this->Data[3] = w; } /** * Get the w component of the vector, i.e. element 3. */ const T& GetW() const { return this->Data[3]; } //@} }; /** * Some inline functions for the derived types. */ #define vtkVectorNormalized(vectorType, type, size) \ vectorType Normalized() const \ { \ return vectorType(vtkVector::Normalized().GetData()); \ } #define vtkVectorDerivedMacro(vectorType, type, size) \ vtkVectorNormalized(vectorType, type, size); \ explicit vectorType(type s) \ : Superclass(s) \ { \ } \ explicit vectorType(const type* i) \ : Superclass(i) \ { \ } \ explicit vectorType(const vtkTuple& o) \ : Superclass(o.GetData()) \ { \ } \ vectorType(const vtkVector& o) \ : Superclass(o.GetData()) \ { \ } //@{ /** * Some derived classes for the different vectors commonly used. */ class vtkVector2i : public vtkVector2 { public: typedef vtkVector2 Superclass; vtkVector2i() {} vtkVector2i(int x, int y) : vtkVector2(x, y) { } vtkVectorDerivedMacro(vtkVector2i, int, 2); }; //@} class vtkVector2f : public vtkVector2 { public: typedef vtkVector2 Superclass; vtkVector2f() {} vtkVector2f(float x, float y) : vtkVector2(x, y) { } vtkVectorDerivedMacro(vtkVector2f, float, 2); }; class vtkVector2d : public vtkVector2 { public: typedef vtkVector2 Superclass; vtkVector2d() {} vtkVector2d(double x, double y) : vtkVector2(x, y) { } vtkVectorDerivedMacro(vtkVector2d, double, 2); }; #define vtkVector3Cross(vectorType, type) \ vectorType Cross(const vectorType& other) const \ { \ return vectorType(vtkVector3::Cross(other).GetData()); \ } class vtkVector3i : public vtkVector3 { public: typedef vtkVector3 Superclass; vtkVector3i() {} vtkVector3i(int x, int y, int z) : vtkVector3(x, y, z) { } vtkVectorDerivedMacro(vtkVector3i, int, 3); vtkVector3Cross(vtkVector3i, int); }; class vtkVector3f : public vtkVector3 { public: typedef vtkVector3 Superclass; vtkVector3f() {} vtkVector3f(float x, float y, float z) : vtkVector3(x, y, z) { } vtkVectorDerivedMacro(vtkVector3f, float, 3); vtkVector3Cross(vtkVector3f, float); }; class vtkVector3d : public vtkVector3 { public: typedef vtkVector3 Superclass; vtkVector3d() {} vtkVector3d(double x, double y, double z) : vtkVector3(x, y, z) { } vtkVectorDerivedMacro(vtkVector3d, double, 3); vtkVector3Cross(vtkVector3d, double); }; class vtkVector4d : public vtkVector4 { public: using Superclass = vtkVector4; vtkVector4d() {} vtkVector4d(double x, double y, double z, double w) : vtkVector4(x, y, z, w){}; vtkVectorDerivedMacro(vtkVector4d, double, 4); }; #endif // vtkVector_h // VTK-HeaderTest-Exclude: vtkVector.h