00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef MITKLINE_H_HEADER_INCLUDED_C19C01E2
00020 #define MITKLINE_H_HEADER_INCLUDED_C19C01E2
00021
00022 #include "mitkVector.h"
00023 #include <vnl/vnl_vector.h>
00024 #include <vnl/vnl_cross.h>
00025 #include <itkTransform.h>
00026 #include <itkMatrix.h>
00027
00028 namespace mitk {
00029
00030
00031
00032
00033 template <class TCoordRep, unsigned int NPointDimension=3>
00034 class Line
00035 {
00036 public:
00037 Line()
00038 {
00039 m_Point.Fill(0);
00040 m_Direction.Fill(0);
00041 };
00042
00043
00044
00045
00046
00047 Line( const itk::Point<TCoordRep,NPointDimension>& point, const itk::Vector<TCoordRep,NPointDimension>& direction )
00048 {
00049 this->m_Point = point;
00050 this->m_Direction = direction;
00051 }
00052
00053
00054
00055 const itk::Point<TCoordRep,NPointDimension>& GetPoint() const
00056 {
00057 return m_Point;
00058 }
00059
00060
00061
00062 itk::Point<TCoordRep,NPointDimension>& GetPoint()
00063 {
00064 return m_Point;
00065 }
00066
00067
00068
00069
00070
00071 const itk::Point<TCoordRep,NPointDimension> GetPoint(TCoordRep t) const
00072 {
00073 return m_Point+m_Direction*t;
00074 }
00075
00076
00077
00078 void SetPoint( const itk::Point<TCoordRep,NPointDimension>& point1 )
00079 {
00080 itk::Vector<TCoordRep,NPointDimension> point2;
00081 point2 = m_Point + m_Direction;
00082
00083 m_Point = point1;
00084 m_Direction = point2 - point1;
00085 }
00086
00087
00088
00089 const itk::Vector<TCoordRep,NPointDimension>& GetDirection() const
00090 {
00091 return m_Direction;
00092 }
00093
00094
00095
00096 itk::Vector<TCoordRep,NPointDimension>& GetDirection()
00097 {
00098 return m_Direction;
00099 }
00100
00101
00102
00103 void SetDirection( const itk::Vector<TCoordRep,NPointDimension>& direction )
00104 {
00105 m_Direction = direction;
00106 }
00107
00108
00109
00110
00111
00112 void Set( const itk::Point<TCoordRep,NPointDimension>& point, const itk::Vector<TCoordRep,NPointDimension>& direction ) {
00113
00114 this->m_Point = point;
00115 this->m_Direction = direction;
00116 }
00117
00118
00119
00120 void SetPoints( const itk::Point<TCoordRep,NPointDimension>& point1, const itk::Point<TCoordRep,NPointDimension>& point2 ) {
00121
00122 this->m_Point = point1;
00123
00124 m_Direction = point2 - point1;
00125 }
00126
00127
00128
00129 void SetPoint1( const itk::Point<TCoordRep,NPointDimension>& point1 ) {
00130
00131 itk::Vector<TCoordRep,NPointDimension> point2;
00132 point2 = m_Point + m_Direction;
00133
00134 m_Point = point1;
00135 m_Direction = point2 - point1;
00136 }
00137
00138
00139
00140 const itk::Point<TCoordRep,NPointDimension>& GetPoint1() const
00141 {
00142 return m_Point;
00143 }
00144
00145
00146
00147 void SetPoint2( const itk::Point<TCoordRep,NPointDimension>& point2 )
00148 {
00149 m_Direction = point2 - m_Point;
00150 }
00151
00152
00153
00154 itk::Point<TCoordRep,NPointDimension> GetPoint2() const
00155 {
00156 itk::Point<TCoordRep,NPointDimension> point2;
00157 point2 = m_Point+m_Direction;
00158 return point2;
00159 }
00160
00161
00162
00163 void Transform(itk::Transform<TCoordRep, NPointDimension, NPointDimension>& transform)
00164 {
00165 m_Direction = transform.TransformVector(m_Direction);
00166 m_Point = transform.TransformPoint(m_Point);
00167 }
00168
00169
00170
00171
00172
00173 void Transform( const itk::Matrix<TCoordRep, NPointDimension, NPointDimension>& matrix )
00174 {
00175 m_Direction = matrix*m_Direction;
00176 }
00177
00178
00179
00180 double Distance( const Line<TCoordRep,NPointDimension>& line ) const;
00181
00182
00183
00184 double Distance( const itk::Point<TCoordRep,NPointDimension>& point ) const
00185 {
00186 itk::Vector<TCoordRep,NPointDimension> diff;
00187 diff = Project(point)-point;
00188 return diff.GetNorm();
00189 }
00190
00191
00192
00193 itk::Point<TCoordRep,NPointDimension> Project( const itk::Point<TCoordRep,NPointDimension>& point ) const
00194 {
00195 if(m_Direction.GetNorm()==0)
00196 return this->m_Point;
00197
00198 itk::Vector<TCoordRep,NPointDimension> diff;
00199 diff = point-this->m_Point;
00200
00201 itk::Vector<TCoordRep,NPointDimension> normalizedDirection = m_Direction;
00202 normalizedDirection.Normalize();
00203
00204 normalizedDirection *= dot_product(diff.Get_vnl_vector(), normalizedDirection.Get_vnl_vector());
00205
00206 return this->m_Point + normalizedDirection;
00207 }
00208
00209
00210
00211
00212
00213 bool IsPartOfStraightLine( const itk::Point<TCoordRep,NPointDimension>& point ) const
00214 {
00215 if( Distance( point ) > eps )
00216 return false;
00217
00218 itk::Vector<TCoordRep,NPointDimension> diff;
00219 diff = point - this->m_Point;
00220
00221 if( diff*m_Direction < 0 )
00222 return false;
00223
00224 if( diff.GetSquaredNorm() <= m_Direction.GetSquaredNorm() )
00225 return true;
00226
00227 return false;
00228 }
00229
00230
00231
00232 bool IsPartOfLine( const itk::Point<TCoordRep,NPointDimension>& point ) const {
00233
00234 if ( Distance( point ) < eps )
00235 return true;
00236
00237 return false;
00238 }
00239
00240
00241
00242 bool IsParallel( const Line<TCoordRep,NPointDimension>& line) const
00243 {
00244 vnl_vector<TCoordRep> normal;
00245
00246 normal = vnl_cross_3d( m_Direction.Get_vnl_vector(), line.GetDirection().Get_vnl_vector() );
00247
00248 if ( normal.squared_magnitude() < eps )
00249 return true;
00250
00251 return false;
00252 }
00253
00254
00255
00256 bool IsPartOfLine( const Line<TCoordRep,NPointDimension>& line ) const
00257 {
00258 return ( Distance( line.GetPoint() ) < 0 ) && ( IsParallel( line ) );
00259 }
00260
00261
00262
00263
00264
00265
00266 bool operator==( const Line<TCoordRep,NPointDimension>& line ) const
00267 {
00268 itk::Vector<TCoordRep,NPointDimension> diff;
00269 diff = GetPoint1()-line.GetPoint1();
00270 if(diff.GetSquaredNorm() > eps)
00271 return false;
00272 diff = GetPoint2()-line.GetPoint2();
00273 if(diff.GetSquaredNorm() > eps)
00274 return false;
00275 return true;
00276 }
00277
00278
00279
00280 inline const Line<TCoordRep,NPointDimension>& operator=( const Line<TCoordRep,NPointDimension>& line )
00281 {
00282 m_Point = line.GetPoint();
00283 m_Direction = line.GetDirection();
00284 return *this;
00285 }
00286
00287
00288
00289
00290
00291 bool operator!=( const Line<TCoordRep,NPointDimension>& line ) const
00292 {
00293 return !((*this)==line);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 static int RectangleLineIntersection(
00306 TCoordRep x1, TCoordRep y1,
00307 TCoordRep x2, TCoordRep y2,
00308 itk::Point< TCoordRep, 2 > p, itk::Vector< TCoordRep, 2 > d,
00309 itk::Point< TCoordRep, 2 > &s1, itk::Point< TCoordRep, 2 > &s2 )
00310 {
00311 int s_num;
00312 TCoordRep t;
00313 s_num=0;
00314
00315
00316 if(fabs(d[0])>eps)
00317 {
00318 t=(x1-p[0])/d[0];
00319 itk::Point<TCoordRep,2> l=p+d*t;
00320 if((l[1]>=y1) && (l[1]<y2))
00321 {
00322 if(s_num) s2=l; else s1=l; ++s_num;
00323 }
00324 }
00325
00326 if(fabs(d[0])>eps)
00327 {
00328 t=(x2-p[0])/d[0];
00329 itk::Point<TCoordRep,2> l=p+d*t;
00330
00331 if((l[1]>=y1) && (l[1]<y2))
00332 {
00333 if(s_num) s2=l; else s1=l; ++s_num;
00334 }
00335 }
00336
00337
00338 if(fabs(d[1])>eps)
00339 {
00340 t=(y1-p[1])/d[1];
00341 itk::Point<TCoordRep,2> l=p+d*t;
00342
00343 if((l[0]>=x1) && (l[0]<x2))
00344 {
00345 if(s_num) s2=l; else s1=l; ++s_num;
00346 }
00347 }
00348
00349 if(fabs(d[1])>eps)
00350 {
00351 t=(y2-p[1])/d[1];
00352 itk::Point<TCoordRep,2> l=p+d*t;
00353 if((l[0]>=x1) && (l[0]<x2))
00354 {
00355 if(s_num) s2=l; else s1=l; ++s_num;
00356 }
00357 }
00358 return s_num;
00359 }
00360
00361
00373 static int BoxLineIntersection(
00374 TCoordRep x1, TCoordRep y1, TCoordRep z1,
00375 TCoordRep x2, TCoordRep y2, TCoordRep z2,
00376 itk::Point< TCoordRep, 3 > p, itk::Vector< TCoordRep, 3 > d,
00377 itk::Point< TCoordRep, 3 > &s1, itk::Point< TCoordRep, 3 > &s2 )
00378 {
00379 int num = 0;
00380
00381 ScalarType box[6];
00382 box[0] = x1; box[1] = x2;
00383 box[2] = y1; box[3] = y2;
00384 box[4] = z1; box[5] = z2;
00385
00386 itk::Point< TCoordRep, 3 > point;
00387
00388 int i, j;
00389 for ( i = 0; i < 6; ++i )
00390 {
00391 j = i / 2;
00392 if ( fabs( d[j] ) > eps )
00393 {
00394 ScalarType lambda = (box[i] - p[j]) / d[j];
00395
00396 point = p + d * lambda;
00397
00398 int k = (j + 1) % 3;
00399 int l = (j + 2) % 3;
00400
00401 if ( (point[k] >= box[k*2]) && (point[k] <= box[k*2+1])
00402 && (point[l] >= box[l*2]) && (point[l] <= box[l*2+1]) )
00403 {
00404 if ( num == 0 )
00405 {
00406 s1 = point;
00407 }
00408 else
00409 {
00410 s2 = point;
00411 }
00412 ++num;
00413 }
00414 }
00415 }
00416 return num;
00417 }
00418
00419
00420 protected:
00421 itk::Point<TCoordRep,NPointDimension> m_Point;
00422 itk::Vector<TCoordRep,NPointDimension> m_Direction;
00423 };
00424
00425 typedef Line<ScalarType, 3> Line3D;
00426
00427 }
00428 #endif
00429