/*============================================================================= NOTE: THIS FILE IS A HANDMADE WRAPPER FOR THE ManagedITK PROJECT. Project: ManagedITK Program: Insight Segmentation & Registration Toolkit Module: itkManagedVector.cxx Language: C++/CLI Author: Dan Mueller $Date: 2007-05-18 06:51:39 +1000 (Fri, 18 May 2007) $ $Revision: 162 $ Copyright (c) Queensland University of Technology (QUT) 2007. All rights reserved. Portions of this code are covered under the ITK and VTK copyright. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. See VTKCopyright.txt or http://www.kitware.com/VTKCopyright.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 notices for more information. =============================================================================*/ #pragma once #pragma warning( disable : 4635 ) // Disable warnings about XML doc comments #ifndef __itkManagedVector_cxx #define __itkManagedVector_cxx // Use some managed namespaces #using #using using namespace System; using namespace System::IO; using namespace System::Reflection; using namespace System::ComponentModel; using namespace System::Diagnostics; // Include Array #include "itkManagedArray.cxx" namespace itk { #define itkVectorValueType System::Double /// ///This class is a managed replacement for itk::Vector. /// /// ///Vector is a class that holds an n-Dimensional vector of values. It ///can be used as the data type held at each pixel in an Image or as ///a data type for the mathematical 'vector'. /// public ref class itkVector : itkArray { public: ///Constructor taking the data values as a params array. ///The variable length data array. The dimension will be initialised as data.Length. itkVector ( ... array^ data ) : itkArray( data ) { } ///Constructor taking the number of dimensions for the array. ///The data values are initialised as zero. ///The dimensionality of the array to initialise. itkVector( unsigned int dimension ) : itkArray( dimension ) { } ///Constructor taking another array. ///Another array to clone the data from. itkVector ( itkVector^ other) : itkArray( other->Data ) { } /// ///Compares the given Object to this. ///They are equal if they have the same dimensionality AND data. /// ///The object to test. ///true AND the objects are equal OR false AND the objects are not equal. virtual bool Equals(Object^ obj) override { // Check if input object is null if ( obj == nullptr ) return false; // Cast itkVector^ right = safe_cast< itkVector^ >(obj); if ( right != nullptr ) { // Check number of dimensions are the same if (this->Dimension != right->Dimension) return false; // Check data at each location is the the same bool result = true; for (unsigned int i = 0; i < this->Dimension; i++) result &= (this[i] == right[i]); return result; } return false; } /// ///Compares two itkVector objects. ///They are equal if they have the same dimensionality AND data. /// /// /// ///true AND the objects are equal OR false AND the objects are not equal. static bool operator ==(itkVector^ lhs, itkVector^ rhs) { if ( Object::ReferenceEquals(lhs, rhs) ) return true; else if ( Object::ReferenceEquals(lhs, nullptr) ) return false; else if ( Object::ReferenceEquals(rhs, nullptr) ) return false; else return lhs->Equals(rhs); } /// ///Compares two itkVector objects. ///They are not equal if they do not have the same dimensionality OR ///do not have the same data. /// /// ///true AND the objects are not equal OR false AND the objects are equal. virtual bool operator !=(itkVector^ rhs) { return !(this == rhs); } ///Performs an element-wise addition. /// /// ///A new itkVector instance with data as the element-wise addition. static itkVector^ operator+(itkVector^ lhs, itkVector^ rhs) { if ( lhs == nullptr || rhs == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); else { itkVector^ result = gcnew itkVector( lhs->Dimension ); for (unsigned int i = 0; i < result->Dimension; i++) result[i] = lhs[i] + rhs[i]; return result; } } ///Performs an element-wise subtraction. /// /// ///A new itkVector instance with data as the element-wise subtraction. static itkVector^ operator-(itkVector^ lhs, itkVector^ rhs) { if ( lhs == nullptr || rhs == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); else { itkVector^ result = gcnew itkVector( lhs->Dimension ); for (unsigned int i = 0; i < result->Dimension; i++) result[i] = lhs[i] - rhs[i]; return result; } } ///Multiply by a scalar value. /// /// ///A new itkVector instance with each data element multiplied by the scalar. static itkVector^ operator*(itkVector^ lhs, double scalar) { if ( lhs == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); else { itkVector^ result = gcnew itkVector( lhs->Dimension ); for (unsigned int i = 0; i < result->Dimension; i++) result[i] = lhs[i] * scalar; return result; } } ///Multiply by a scalar value. /// /// ///A new itkVector instance with each data element multiplied by the scalar. static itkVector^ operator*(double scalar, itkVector^ rhs) { if ( rhs == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); else { itkVector^ result = gcnew itkVector( rhs->Dimension ); for (unsigned int i = 0; i < result->Dimension; i++) result[i] = rhs[i] * scalar; return result; } } ///Divide by a scalar value. /// /// ///A new itkVector instance with each data element divided by the scalar. static itkVector^ operator/(itkVector^ lhs, double scalar) { if ( lhs == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); else { itkVector^ result = gcnew itkVector( lhs->Dimension ); for (unsigned int i = 0; i < result->Dimension; i++) result[i] = lhs[i] / scalar; return result; } } ///Divide by a scalar value. /// /// ///A new itkVector instance with each data element divided by the scalar. static itkVector^ operator/(double scalar, itkVector^ rhs) { if ( rhs == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); else { itkVector^ result = gcnew itkVector( rhs->Dimension ); for (unsigned int i = 0; i < result->Dimension; i++) result[i] = rhs[i] / scalar; return result; } } ///Computes the Euclidean norm (magnitude) of the vector. ///The Euclidean norm (magnitude) of the vector. double GetNorm() { return Math::Sqrt(this->GetSquaredNorm()); } ///Computes the squared Euclidean (magnitude) of the vector. ///The squared Euclidean norm (magnitude) of the vector. double GetSquaredNorm() { double result = 0.0; for (unsigned int i = 0; i < this->Dimension; i++) result += this[i] * this[i]; return result; } ///Normalizes this instance of the vector. ie. Divides each comonent by GetNorm(). void Normalize() { double norm = this->GetNorm(); for (unsigned int i = 0; i < this->Dimension; i++) this[i] /= norm; } ///Computes and returns the dot product of two vectors. static itkVectorValueType Dot( itkVector^ a, itkVector^ b ) { if ( a == nullptr || b == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); if ( a->Length != b->Length ) throw gcnew ArgumentException("Vector lengths do not match."); itkVectorValueType result = 0.0; for( unsigned int i=0; i < a->Length; i++ ) { result += a[i] * b[i]; } return result; } ///Computes and returns the cross product of two vectors. ///This operation is only defined for vectors of length 3. static itkVector^ Cross( itkVector^ a, itkVector^ b ) { if ( a == nullptr || b == nullptr ) throw gcnew ArgumentNullException("Can not operate on nullptr objects."); if ( a->Length != 3 && b->Length != 3 ) throw gcnew ArgumentException("Cross product is only defined for vectors of length 3."); itkVector^ c = gcnew itkVector( a->Length ); c[0] = a[1] * b[2] - a[2] * b[1]; c[1] = a[2] * b[0] - a[0] * b[2]; c[2] = a[0] * b[1] - a[1] * b[0]; return c; } }; // end ref class } // end namespace itk #endif