00001 /*========================================================================= 00002 00003 Program: Insight Segmentation & Registration Toolkit 00004 Module: $RCSfile: PointSetWithCovariantVectors.cxx,v $ 00005 Language: C++ 00006 Date: $Date: 2008/01/20 21:19:51 $ 00007 Version: $Revision: 1.15 $ 00008 00009 Copyright (c) Insight Software Consortium. All rights reserved. 00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 #if defined(_MSC_VER) 00018 #pragma warning ( disable : 4786 ) 00019 #endif 00020 00021 // Software Guide : BeginLatex 00022 // 00023 // It is common to represent geometric object by using points on their surfaces 00024 // and normals associated with those points. This structure can be easily 00025 // instantiated with the \doxygen{PointSet} class. 00026 // 00027 // The natural class for representing normals to surfaces and 00028 // gradients of functions is the \doxygen{CovariantVector}. A 00029 // covariant vector differs from a vector in the way they behave 00030 // under affine transforms, in particular under anisotropic 00031 // scaling. If a covariant vector represents the gradient of a 00032 // function, the transformed covariant vector will still be the valid 00033 // gradient of the transformed function, a property which would not 00034 // hold with a regular vector. 00035 // 00036 // \index{itk::PointSet!itk::CovariantVector} 00037 // \index{itk::CovariantVector!itk::PointSet} 00038 // 00039 // The following code shows how vector values can be used as pixel type on the 00040 // PointSet class. The CovariantVector class is used here as the 00041 // pixel type. The example illustrates how a deformable model could move under 00042 // the influence of the gradient of potential function. 00043 // 00044 // In order to use the CovariantVector class it is necessary to 00045 // include its header file along with the header of the point set. 00046 // 00047 // \index{itk::CovariantVector!Header} 00048 // 00049 // Software Guide : EndLatex 00050 00051 // Software Guide : BeginCodeSnippet 00052 #include "itkCovariantVector.h" 00053 #include "itkPointSet.h" 00054 // Software Guide : EndCodeSnippet 00055 00056 int main(int, char *[]) 00057 { 00058 // Software Guide : BeginLatex 00059 // 00060 // The CovariantVector class is templated over the type used to 00061 // represent the spatial coordinates and over the space dimension. Since 00062 // the PixelType is independent of the PointType, we are free to select any 00063 // dimension for the covariant vectors to be used as pixel type. However, we 00064 // want to illustrate here the spirit of a deformable model. It is then 00065 // required for the vectors representing gradients to be of the same 00066 // dimension as the points in space. 00067 // 00068 // \index{itk::CovariantVector!Instantiation} 00069 // 00070 // Software Guide : EndLatex 00071 00072 // Software Guide : BeginCodeSnippet 00073 const unsigned int Dimension = 3; 00074 typedef itk::CovariantVector< float, Dimension > PixelType; 00075 // Software Guide : EndCodeSnippet 00076 00077 00078 // Software Guide : BeginLatex 00079 // 00080 // Then we use the PixelType (which are actually CovariantVectors) to 00081 // instantiate the PointSet type and subsequently create a PointSet object. 00082 // 00083 // Software Guide : EndLatex 00084 00085 // Software Guide : BeginCodeSnippet 00086 typedef itk::PointSet< PixelType, Dimension > PointSetType; 00087 PointSetType::Pointer pointSet = PointSetType::New(); 00088 // Software Guide : EndCodeSnippet 00089 00090 00091 // Software Guide : BeginLatex 00092 // 00093 // The following code generates a sphere and assigns gradient values to 00094 // the points. The components of the CovariantVectors in this example are 00095 // computed to represent the normals to the circle. 00096 // 00097 // \index{itk::PointSet!SetPoint()} 00098 // \index{itk::PointSet!SetPointData()} 00099 // 00100 // Software Guide : EndLatex 00101 00102 // Software Guide : BeginCodeSnippet 00103 PointSetType::PixelType gradient; 00104 PointSetType::PointType point; 00105 00106 unsigned int pointId = 0; 00107 const double radius = 300.0; 00108 00109 for(unsigned int i=0; i<360; i++) 00110 { 00111 const double angle = i * atan(1.0) / 45.0; 00112 point[0] = radius * sin( angle ); 00113 point[1] = radius * cos( angle ); 00114 point[2] = 1.0; // flat on the Z plane 00115 gradient[0] = sin(angle); 00116 gradient[1] = cos(angle); 00117 gradient[2] = 0.0; // flat on the Z plane 00118 pointSet->SetPoint( pointId, point ); 00119 pointSet->SetPointData( pointId, gradient ); 00120 pointId++; 00121 } 00122 // Software Guide : EndCodeSnippet 00123 00124 00125 // Software Guide : BeginLatex 00126 // 00127 // We can now visit all the points and use the vector on the pixel values 00128 // to apply a deformation on the points by following the gradient of the 00129 // function. This is along the spirit of what a deformable model could do 00130 // at each one of its iterations. To be more formal we should use the 00131 // function gradients as forces and multiply them by local stress tensors 00132 // in order to obtain local deformations. The resulting deformations 00133 // would finally be used to apply displacements on the points. However, 00134 // to shorten the example, we will ignore this complexity for the moment. 00135 // 00136 // \index{itk::PointSet!PointDataIterator} 00137 // 00138 // Software Guide : EndLatex 00139 00140 00141 // Software Guide : BeginCodeSnippet 00142 typedef PointSetType::PointDataContainer::ConstIterator PointDataIterator; 00143 PointDataIterator pixelIterator = pointSet->GetPointData()->Begin(); 00144 PointDataIterator pixelEnd = pointSet->GetPointData()->End(); 00145 00146 typedef PointSetType::PointsContainer::Iterator PointIterator; 00147 PointIterator pointIterator = pointSet->GetPoints()->Begin(); 00148 PointIterator pointEnd = pointSet->GetPoints()->End(); 00149 00150 while( pixelIterator != pixelEnd && pointIterator != pointEnd ) 00151 { 00152 point = pointIterator.Value(); 00153 gradient = pixelIterator.Value(); 00154 for(unsigned int i=0; i<Dimension; i++) 00155 { 00156 point[i] += gradient[i]; 00157 } 00158 pointIterator.Value() = point; 00159 ++pixelIterator; 00160 ++pointIterator; 00161 } 00162 // Software Guide : EndCodeSnippet 00163 00164 00165 // Software Guide : BeginLatex 00166 // 00167 // The CovariantVector class does not overload the \code{+} 00168 // operator with the \doxygen{Point}. In other words, CovariantVectors can 00169 // not be added to points in order to get new points. Further, since we 00170 // are ignoring physics in the example, we are also forced to do the 00171 // illegal addition manually between the components of the gradient and 00172 // the coordinates of the points. 00173 // 00174 // Note that the absence of some basic operators on the ITK geometry classes 00175 // is completely intentional with the aim of preventing the incorrect use 00176 // of the mathematical concepts they represent. 00177 // 00178 // \index{itk::CovariantVector} 00179 // 00180 // Software Guide : EndLatex 00181 // 00182 00183 00184 // We can finally visit all the points and print out the new values. 00185 // 00186 pointIterator = pointSet->GetPoints()->Begin(); 00187 pointEnd = pointSet->GetPoints()->End(); 00188 while( pointIterator != pointEnd ) 00189 { 00190 std::cout << pointIterator.Value() << std::endl; 00191 ++pointIterator; 00192 } 00193 00194 00195 return 0; 00196 } 00197 00198 00199