00001 /*========================================================================= 00002 00003 Program: Insight Segmentation & Registration Toolkit 00004 Module: $RCSfile: PointSetWithVectors.cxx,v $ 00005 Language: C++ 00006 Date: $Date: 2005-11-19 16:31:49 $ 00007 Version: $Revision: 1.17 $ 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 // This example illustrates how a point set can be parameterized to manage a 00024 // particular pixel type. It is quite common to associate vector values with 00025 // points for producing geometric representations. The following code shows 00026 // how vector values can be used as pixel type on the PointSet class. The 00027 // \doxygen{Vector} class is used here as the pixel type. This class is 00028 // appropriate for representing the relative position between two points. It 00029 // could then be used to manage displacements, for example. 00030 // 00031 // \index{itk::PointSet!Vector pixels} 00032 // 00033 // In order to use the vector class it is necessary to include its header file 00034 // along with the header of the point set. 00035 // 00036 // Software Guide : EndLatex 00037 00038 // Software Guide : BeginCodeSnippet 00039 #include "itkVector.h" 00040 #include "itkPointSet.h" 00041 // Software Guide : EndCodeSnippet 00042 00043 00044 int main(int, char *[]) 00045 { 00046 // Software Guide : BeginLatex 00047 // 00048 // \itkpiccaption[PointSet with Vectors as PixelType]{Vectors as PixelType.\label{fig:PointSetWithVectors}} 00049 // \parpic(6cm,4cm)[r]{\includegraphics[width=4cm]{PointSetWithVectors.eps}} 00050 // 00051 // The Vector class is templated over the type used to represent 00052 // the spatial coordinates and over the space dimension. Since the 00053 // PixelType is independent of the PointType, we are free to select any 00054 // dimension for the vectors to be used as pixel type. However, for the 00055 // sake of producing an interesting example, we will use vectors that 00056 // represent displacements of the points in the PointSet. Those vectors 00057 // are then selected to be of the same dimension as the PointSet. 00058 // 00059 // \index{itk::Vector!itk::PointSet} 00060 // 00061 // Software Guide : EndLatex 00062 00063 // Software Guide : BeginCodeSnippet 00064 const unsigned int Dimension = 3; 00065 typedef itk::Vector< float, Dimension > PixelType; 00066 // Software Guide : EndCodeSnippet 00067 00068 00069 // Software Guide : BeginLatex 00070 // 00071 // Then we use the PixelType (which are actually Vectors) to instantiate the 00072 // PointSet type and subsequently create a PointSet object. 00073 // 00074 // Software Guide : EndLatex 00075 00076 // Software Guide : BeginCodeSnippet 00077 typedef itk::PointSet< PixelType, Dimension > PointSetType; 00078 PointSetType::Pointer pointSet = PointSetType::New(); 00079 // Software Guide : EndCodeSnippet 00080 00081 00082 // Software Guide : BeginLatex 00083 // 00084 // The following code is generating a sphere and assigning vector values 00085 // to the points. The components of the vectors in this example are 00086 // computed to represent the tangents to the circle as shown in 00087 // Figure~\ref{fig:PointSetWithVectors}. 00088 // 00089 // \index{itk::PointSet!SetPoint()} 00090 // \index{itk::PointSet!SetPointData()} 00091 // 00092 // Software Guide : EndLatex 00093 00094 // Software Guide : BeginCodeSnippet 00095 PointSetType::PixelType tangent; 00096 PointSetType::PointType point; 00097 00098 unsigned int pointId = 0; 00099 const double radius = 300.0; 00100 00101 for(unsigned int i=0; i<360; i++) 00102 { 00103 const double angle = i * atan(1.0) / 45.0; 00104 point[0] = radius * sin( angle ); 00105 point[1] = radius * cos( angle ); 00106 point[2] = 1.0; // flat on the Z plane 00107 tangent[0] = cos(angle); 00108 tangent[1] = -sin(angle); 00109 tangent[2] = 0.0; // flat on the Z plane 00110 pointSet->SetPoint( pointId, point ); 00111 pointSet->SetPointData( pointId, tangent ); 00112 pointId++; 00113 } 00114 // Software Guide : EndCodeSnippet 00115 00116 00117 // Software Guide : BeginLatex 00118 // 00119 // We can now visit all the points and use the vector on the pixel values to 00120 // apply a displacement on the points. This is along the spirit of what a 00121 // deformable model could do at each one of its iterations. 00122 // 00123 // \index{itk::PointSet!PointIterator} 00124 // \index{itk::PointSet!GetPoints()} 00125 // \index{itk::PointSet!GetPointData()} 00126 // 00127 // Software Guide : EndLatex 00128 00129 00130 // Software Guide : BeginCodeSnippet 00131 typedef PointSetType::PointDataContainer::ConstIterator PointDataIterator; 00132 PointDataIterator pixelIterator = pointSet->GetPointData()->Begin(); 00133 PointDataIterator pixelEnd = pointSet->GetPointData()->End(); 00134 00135 typedef PointSetType::PointsContainer::Iterator PointIterator; 00136 PointIterator pointIterator = pointSet->GetPoints()->Begin(); 00137 PointIterator pointEnd = pointSet->GetPoints()->End(); 00138 00139 while( pixelIterator != pixelEnd && pointIterator != pointEnd ) 00140 { 00141 pointIterator.Value() = pointIterator.Value() + pixelIterator.Value(); 00142 ++pixelIterator; 00143 ++pointIterator; 00144 } 00145 // Software Guide : EndCodeSnippet 00146 00147 00148 // Software Guide : BeginLatex 00149 // 00150 // Note that the \code{ConstIterator} was used here instead of the normal 00151 // \code{Iterator} since the pixel values are only intended to be read and 00152 // not modified. ITK supports const-correctness at the API level. 00153 // 00154 // \index{ConstIterator} 00155 // \index{const-correctness} 00156 // 00157 // Software Guide : EndLatex 00158 00159 00160 // Software Guide : BeginLatex 00161 // 00162 // The \doxygen{Vector} class has overloaded the \code{+} operator with 00163 // the \doxygen{Point}. In other words, vectors can be added to points in 00164 // order to produce new points. This property is exploited in the center 00165 // of the loop in order to update the points positions with a single 00166 // statement. 00167 // 00168 // \index{itk::PointSet!PointIterator} 00169 // 00170 // We can finally visit all the points and print out the new values 00171 // 00172 // Software Guide : EndLatex 00173 00174 // Software Guide : BeginCodeSnippet 00175 pointIterator = pointSet->GetPoints()->Begin(); 00176 pointEnd = pointSet->GetPoints()->End(); 00177 while( pointIterator != pointEnd ) 00178 { 00179 std::cout << pointIterator.Value() << std::endl; 00180 ++pointIterator; 00181 } 00182 // Software Guide : EndCodeSnippet 00183 00184 00185 // Software Guide : BeginLatex 00186 // 00187 // Note that \doxygen{Vector} is not the appropriate class for 00188 // representing normals to surfaces and gradients of functions. This is due 00189 // to the way in which vectors behave under affine transforms. ITK has a 00190 // specific class for representing normals and function gradients. This is 00191 // the \doxygen{CovariantVector} class. 00192 // 00193 // Software Guide : EndLatex 00194 00195 return 0; 00196 } 00197 00198 00199