| 1 |
|
/*========================================================================= |
| 2 |
|
|
| 3 |
|
Program: Insight Segmentation & Registration Toolkit |
| 4 |
|
Module: $RCSfile: itkPoint.h.html,v $ |
| 5 |
|
Language: C++ |
| 6 |
|
Date: $Date: 2006/01/17 19:15:43 $ |
| 7 |
|
Version: $Revision: 1.4 $ |
| 8 |
|
|
| 9 |
|
Copyright (c) Insight Software Consortium. All rights reserved. |
| 10 |
|
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. |
| 11 |
|
|
| 12 |
|
This software is distributed WITHOUT ANY WARRANTY; without even |
| 13 |
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| 14 |
|
PURPOSE. See the above copyright notices for more information. |
| 15 |
|
|
| 16 |
|
=========================================================================*/ |
| 17 |
|
#ifndef __itkPoint_h |
| 18 |
|
#define __itkPoint_h |
| 19 |
|
|
| 20 |
|
#include "itkVector.h" |
| 21 |
|
#include "vnl/vnl_vector_ref.h" |
| 22 |
|
#include "itkIndent.h" |
| 23 |
|
|
| 24 |
|
namespace itk |
| 25 |
|
{ |
| 26 |
|
/** \class Point |
| 27 |
|
* \brief A templated class holding a geometric point in n-Dimensional space. |
| 28 |
|
* |
| 29 |
|
* Point is a templated class that holds a set of coordinates (components). |
| 30 |
|
* Point can be used as the data type held at each pixel in |
| 31 |
|
* an Image or at each vertex of an Mesh. The template parameter T can |
| 32 |
|
* be any data type that behaves like a primitive (or atomic) data type (int, |
| 33 |
|
* short, float, complex). The NPointDimension defines the number of |
| 34 |
|
* components in the point array. |
| 35 |
|
* |
| 36 |
|
* \ingroup Geometry |
| 37 |
|
* \ingroup DataRepresentation |
| 38 |
|
* |
| 39 |
|
* \sa Image \sa Mesh \sa Vector \sa CovariantVector \sa Matrix |
| 40 |
|
*/ |
| 41 |
|
template<class TCoordRep, unsigned int NPointDimension=3> |
| 42 |
|
class Point : public FixedArray< TCoordRep, NPointDimension > |
| 43 |
|
{ |
| 44 |
|
public: |
| 45 |
|
/** Standard class typedefs. */ |
| 46 |
|
typedef Point Self; |
| 47 |
TDA |
typedef FixedArray<TCoordRep,NPointDimension> Superclass; |
| 48 |
|
|
| 49 |
|
/** ValueType can be used to declare a variable that is the same type |
| 50 |
|
* as a data element held in an Point. */ |
| 51 |
|
typedef TCoordRep ValueType; |
| 52 |
|
typedef TCoordRep CoordRepType; |
| 53 |
|
|
| 54 |
|
typedef typename NumericTraits< ValueType >::RealType RealType; |
| 55 |
|
|
| 56 |
|
/** Dimension of the Space */ |
| 57 |
|
itkStaticConstMacro(PointDimension, unsigned int, NPointDimension); |
| 58 |
|
|
| 59 |
|
/** The Array type from which this Vector is derived. */ |
| 60 |
|
typedef FixedArray<TCoordRep, NPointDimension> BaseArray; |
| 61 |
TDA |
typedef typename BaseArray::Iterator Iterator; |
| 62 |
TDA |
typedef typename BaseArray::ConstIterator ConstIterator; |
| 63 |
|
|
| 64 |
|
/** Get the dimension (size) of the point. */ |
| 65 |
|
static unsigned int GetPointDimension() |
| 66 |
|
{ return NPointDimension; } |
| 67 |
|
|
| 68 |
|
/** VectorType define the difference between two Points */ |
| 69 |
|
typedef Vector< ValueType, NPointDimension > VectorType; |
| 70 |
|
|
| 71 |
|
/** Default constructor has nothing to do. */ |
| 72 |
|
Point() {} |
| 73 |
|
|
| 74 |
|
/** Pass-through constructor for the Array base class. */ |
| 75 |
|
Point(const Self& r): BaseArray(r) {} |
| 76 |
|
Point(const ValueType r[PointDimension]): BaseArray(r) {} |
| 77 |
|
|
| 78 |
|
/** Pass-through assignment operator for the Array base class. */ |
| 79 |
|
Point& operator= (const Self& r); |
| 80 |
|
Point& operator= (const ValueType r[NPointDimension]); |
| 81 |
|
|
| 82 |
|
/** Compare two points for equality. */ |
| 83 |
|
bool |
| 84 |
|
operator==(const Self &pt) const |
| 85 |
|
{ |
| 86 |
|
bool same=true; |
| 87 |
|
for (unsigned int i=0; i < PointDimension && same; i++) |
| 88 |
|
{ same = ((*this)[i] == pt[i]); } |
| 89 |
|
return same; |
| 90 |
|
} |
| 91 |
|
|
| 92 |
|
/** Compare two points for inequality. */ |
| 93 |
|
bool |
| 94 |
|
operator!=(const Self &pt) const |
| 95 |
|
{ |
| 96 |
|
bool same=true; |
| 97 |
|
for (unsigned int i=0; i < PointDimension && same; i++) |
| 98 |
|
{ same = ((*this)[i] == pt[i]); } |
| 99 |
|
return !same; |
| 100 |
|
} |
| 101 |
|
|
| 102 |
|
/** Point operator+=. Adds a vector to the current point. */ |
| 103 |
|
const Self& operator+=(const VectorType &vec); |
| 104 |
|
|
| 105 |
|
/** Point operator-=. Subtracts a vector from a current point. */ |
| 106 |
|
const Self& operator-=(const VectorType &vec); |
| 107 |
|
|
| 108 |
|
/** Computes the Vector difference between two points */ |
| 109 |
|
VectorType operator-(const Self &pnt) const; |
| 110 |
|
|
| 111 |
|
/** Add a vector to a point. Return a new point. */ |
| 112 |
|
Self operator+(const VectorType &vec) const; |
| 113 |
|
|
| 114 |
|
/** Subtract a vector from a point. Return a new point. */ |
| 115 |
|
Self operator-(const VectorType &vec) const; |
| 116 |
|
|
| 117 |
|
/** Access an element of a point. */ |
| 118 |
|
VectorType GetVectorFromOrigin() const; |
| 119 |
|
|
| 120 |
|
/** Get a vnl_vector_ref referencing the same memory block */ |
| 121 |
|
vnl_vector_ref<TCoordRep> GetVnlVector( void ); |
| 122 |
|
|
| 123 |
|
/** Get a vnl_vector with a copy of the internal memory block. */ |
| 124 |
|
vnl_vector<TCoordRep> GetVnlVector( void ) const; |
| 125 |
|
|
| 126 |
|
/** Get a vnl_vector_ref referencing the same memory block |
| 127 |
|
* \deprecated Use GetVnlVector() instead. */ |
| 128 |
|
vnl_vector_ref<TCoordRep> Get_vnl_vector( void ); |
| 129 |
|
|
| 130 |
|
/** Get a vnl_vector with a copy of the internal memory block. |
| 131 |
|
* \deprecated Use GetVnlVector() instead. */ |
| 132 |
|
vnl_vector<TCoordRep> Get_vnl_vector( void ) const; |
| 133 |
|
|
| 134 |
|
/** Set to median point between the two points |
| 135 |
|
* given as arguments |
| 136 |
|
* |
| 137 |
|
* This method computes: |
| 138 |
|
* |
| 139 |
|
* \f[ |
| 140 |
|
* \overrightarrow{P}=\frac{(\overrightarrow{A}+\overrightarrow{B})}{2} |
| 141 |
|
* \f] |
| 142 |
|
* |
| 143 |
|
* using the two Points given as arguments, and store the result in |
| 144 |
|
* the Point on which the method is invoked. */ |
| 145 |
|
void SetToMidPoint( const Self &, const Self & ); |
| 146 |
|
|
| 147 |
|
/** Set the current point to a barycentric combination of the two points |
| 148 |
|
* given as arguments. |
| 149 |
|
* |
| 150 |
|
* \param \f$ \alpha \f$ = weight for the first point |
| 151 |
|
* |
| 152 |
|
* The first point is multiplied by \f$ \alpha \f$, the second is multiplied |
| 153 |
|
* by * \f$ (1-\alpha) \f$, and the sum is stored in the Point on which the |
| 154 |
|
* method is invoked. |
| 155 |
|
* |
| 156 |
|
* \f[ |
| 157 |
LEN |
* \overrightarrow{P}=\alpha * \overrightarrow{A}+ (1-\alpha)*\overrightarrow{B} |
| 158 |
|
* \f] |
| 159 |
|
* |
| 160 |
LEN |
* If the value of \f$ \alpha \in [0,1] \f$, the resulting point will be placed |
| 161 |
LEN |
* in the line segment \f$ \overline{AB} \f$ joining \f$ \overrightarrow{A} \f$ |
| 162 |
|
* and \f$ \overrightarrow{A} \f$ |
| 163 |
|
* |
| 164 |
LEN |
* If the value of \f$ \alpha < 0 \f$ the resulting point will be placed outside |
| 165 |
LEN |
* the line segment \f$ \overline{AB} \f$ on the side of \f$ \overrightarrow{A} \f$. |
| 166 |
|
* |
| 167 |
LEN |
* If the value of \f$ \alpha > 1 \f$ the resulting point will be placed outside |
| 168 |
LEN |
* the line segment \f$ \overline{AB} \f$ on the side of \f$ \overrightarrow{B} \f$. |
| 169 |
|
* |
| 170 |
|
* \sa SetToMedian */ |
| 171 |
LEN |
void SetToBarycentricCombination( const Self & A, const Self & B, double alpha ); |
| 172 |
|
|
| 173 |
|
/** Set the current point to a barycentric combination of three points |
| 174 |
|
* Two values are expected to weight the contribution of the first two points, |
| 175 |
LEN |
* the weight of for the third point is computed to ensure that the three weights |
| 176 |
|
* sum 1. |
| 177 |
|
* |
| 178 |
|
* This method computes: |
| 179 |
|
* |
| 180 |
|
* \f[ |
| 181 |
|
* \overrightarrow{P}= w_1 * \overrightarrow{P}_1 |
| 182 |
IND |
**************************+ w_2 * \overrightarrow{P}_2 |
| 183 |
IND |
**************************+ (1-w_1-w_2 ) * \overrightarrow{P}_3 |
| 184 |
|
* \f] |
| 185 |
|
* |
| 186 |
LEN |
* If the two weight are \f$ \in [0,1] \f$ , The resulting point will alway be placed |
| 187 |
|
* inside the triangle formed by the three points given as arguments. */ |
| 188 |
LEN |
void SetToBarycentricCombination( const Self & A, const Self & B, const Self & C, |
| 189 |
|
double weightA, double weightB ); |
| 190 |
|
|
| 191 |
|
/** Set the current point to a barycentric combination of an array of N points |
| 192 |
|
* An array of (N-1) values is expected to weight the contribution of the |
| 193 |
|
* first (N-1) points, the weight of the Nth point is computed to ensure that |
| 194 |
|
* the N weights sum 1. |
| 195 |
|
* |
| 196 |
|
* This method computes: |
| 197 |
|
* |
| 198 |
|
* \f[ |
| 199 |
|
* \overrightarrow{P}= \sum_{i=1}^{N-1} w_i * \overrightarrow{P}_i |
| 200 |
IND |
**********+ \left(1- \sum_{i=1}^{N-1} w_i\right) * \overrightarrow{P}_N |
| 201 |
|
* \f] |
| 202 |
|
*/ |
| 203 |
LEN |
void SetToBarycentricCombination( const Self * P, const double * weights, unsigned int N); |
| 204 |
|
|
| 205 |
|
|
| 206 |
|
/** Copy from another Point with a different representation type. |
| 207 |
|
* Casting is done with C-Like rules */ |
| 208 |
|
template < typename TCoordRepB > |
| 209 |
|
void CastFrom( const Point<TCoordRepB,NPointDimension> & pa ) |
| 210 |
IND |
**{ |
| 211 |
|
for(unsigned int i=0; i<NPointDimension; i++ ) |
| 212 |
|
{ |
| 213 |
|
(*this)[i] = static_cast<TCoordRep>( pa[i] ); |
| 214 |
|
} |
| 215 |
IND |
**} |
| 216 |
|
|
| 217 |
|
|
| 218 |
|
/** Compute the Squared Euclidean Distance from this point to another point |
| 219 |
LEN,IND |
***** with a different representation type. Casting is done with C-Like rules */ |
| 220 |
|
|
| 221 |
|
template < typename TCoordRepB > |
| 222 |
LEN |
RealType SquaredEuclideanDistanceTo( const Point<TCoordRepB,NPointDimension> & pa ) const |
| 223 |
IND |
**{ |
| 224 |
|
RealType sum = NumericTraits< RealType >::Zero; |
| 225 |
|
for(unsigned int i=0; i<NPointDimension; i++ ) |
| 226 |
|
{ |
| 227 |
|
const RealType component = static_cast< RealType >( pa[i] ); |
| 228 |
|
const ValueType difference = (*this)[i] - component; |
| 229 |
|
sum += difference * difference; |
| 230 |
|
} |
| 231 |
IND |
**return sum; |
| 232 |
IND |
**} |
| 233 |
|
|
| 234 |
|
|
| 235 |
EML |
|
| 236 |
|
/** Compute the Euclidean Distance from this point to another point |
| 237 |
LEN,IND |
***** with a different representation type. Casting is done with C-Like rules */ |
| 238 |
|
template < typename TCoordRepB > |
| 239 |
LEN |
RealType EuclideanDistanceTo( const Point<TCoordRepB,NPointDimension> & pa ) const |
| 240 |
IND |
**{ |
| 241 |
IND |
**const double distance = sqrt( |
| 242 |
SEM |
static_cast<double>( this->SquaredEuclideanDistanceTo( pa ) ) ) ; |
| 243 |
IND |
**return static_cast<RealType>( distance ); |
| 244 |
IND |
**} |
| 245 |
|
|
| 246 |
|
|
| 247 |
|
}; |
| 248 |
|
|
| 249 |
|
template< class T, unsigned int NPointDimension > |
| 250 |
|
ITK_EXPORT std::ostream& operator<<(std::ostream& os, |
| 251 |
|
const Point<T,NPointDimension> & v); |
| 252 |
|
|
| 253 |
|
template< class T, unsigned int NPointDimension > |
| 254 |
|
ITK_EXPORT std::istream& operator>>(std::istream& is, |
| 255 |
|
Point<T,NPointDimension> & v); |
| 256 |
|
|
| 257 |
|
/** Class that computes the barycentric combination of an array of N points |
| 258 |
|
* |
| 259 |
|
* An array of (N-1) values is expected to weight the contribution of the |
| 260 |
|
* first (N-1) points, the weight of the Nth point is computed to ensure that |
| 261 |
|
* the N weights sum 1. |
| 262 |
|
* |
| 263 |
|
* This method computes: |
| 264 |
|
* |
| 265 |
|
* \f[ |
| 266 |
|
* \overrightarrow{P}= \sum_{i=1}^{N-1} w_i * \overrightarrow{P}_i |
| 267 |
|
* + \left(1- \sum_{i=1}^{N-1} w_i\right) * \overrightarrow{P}_N |
| 268 |
|
* \f] |
| 269 |
|
* |
| 270 |
|
* The points are expected to be stored in an itkContainer class like |
| 271 |
|
* itk::VectorContainer, responding to the Begin(), End(), Value() API. |
| 272 |
|
* |
| 273 |
|
* The weights are expected to be stored in any array-like container |
| 274 |
|
* having a operator[i]. |
| 275 |
|
* |
| 276 |
|
* \ingroup Geometry |
| 277 |
|
*/ |
| 278 |
|
template< class TPointContainer, class TWeightContainer > |
| 279 |
|
ITK_EXPORT class BarycentricCombination |
| 280 |
MCM |
{ |
| 281 |
|
public: |
| 282 |
|
/** Convenient typedefs. */ |
| 283 |
|
typedef TPointContainer PointContainerType; |
| 284 |
TDA |
typedef typename PointContainerType::Pointer PointContainerPointer; |
| 285 |
TDA |
typedef typename PointContainerType::Element PointType; |
| 286 |
TDA |
typedef TWeightContainer WeightContainerType; |
| 287 |
|
|
| 288 |
|
BarycentricCombination() {}; |
| 289 |
|
~BarycentricCombination() {}; |
| 290 |
|
|
| 291 |
|
static PointType Evaluate( |
| 292 |
|
const PointContainerPointer & points, |
| 293 |
|
const WeightContainerType & weights ); |
| 294 |
|
}; |
| 295 |
|
|
| 296 |
|
#ifdef ITK_EXPLICIT_INSTANTIATION |
| 297 |
IND |
***extern template class Point<float ,2>; |
| 298 |
IND |
***extern template class Point<double ,2>; |
| 299 |
IND |
***extern template class Point<float ,3>; |
| 300 |
IND |
***extern template class Point<double ,3>; |
| 301 |
|
#endif |
| 302 |
|
|
| 303 |
|
} // end namespace itk |
| 304 |
|
|
| 305 |
|
#ifndef ITK_MANUAL_INSTANTIATION |
| 306 |
|
#include "itkPoint.txx" |
| 307 |
|
#endif |
| 308 |
|
|
| 309 |
|
|
| 310 |
|
#endif |
| 311 |
|
|