OpendTect-6_4  6.4
polylinend.h
Go to the documentation of this file.
1 #ifndef polylinend_h
2 #define polylinend_h
3 
4 /*+
5 ________________________________________________________________________
6 
7  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
8  Author: J.C. Glas
9  Date: Dec 2006
10  RCS: $Id$
11 ________________________________________________________________________
12 
13 -*/
14 
15 #include "math.h"
16 #include "typeset.h"
17 
18 
24 template <class T>
25 mClass(Algo) PolyLineND : public TypeSet<T>
26 {
27 public:
28  PolyLineND(bool closed=false)
29  : closed_( closed ) {}
30 
31  PolyLineND(const TypeSet<T>& coords,bool closed=false)
32  : TypeSet<T>( coords )
33  , closed_( closed ) {}
34 
35  void setClosed(bool yn) { closed_ = yn; }
36  bool isClosed() const { return closed_; }
37 
38  double distTo(const T& pt,int* segmentidxptr=0,
39  double* fractionptr=0) const;
40 
41  T closestPoint(const T& pt) const;
42 
43  double arcLength(int idx,double frac=0.0) const;
44  double arcLength(const T& pt) const;
45  double arcLength() const;
46 
47  T getPoint(int idx,double frac=0.0) const;
48  T getPoint(double arclen) const;
49 
50 protected:
51 
52  int nextIdx(int) const;
53  bool closed_;
54 };
55 
56 
57 template <class T> inline
58 int PolyLineND<T>::nextIdx( int idx ) const
59 {
60  if ( idx<0 || idx>=this->size() || !(*this)[idx].isDefined() )
61  return mUdf(int);
62 
63  int idy = idx + 1;
64  if ( idy>=this->size() || !(*this)[idy].isDefined() )
65  {
66  while ( (--idy)>=0 && (*this)[idy].isDefined() ) ;
67 
68  idy++;
69 
70  if ( !closed_ && idy!=idx )
71  return mUdf(int);
72  }
73 
74  return idy;
75 }
76 
77 
90 #define mUpdateMinDist( dist, idx, frac ) \
91  if ( dist<mindist ) \
92  { \
93  mindist = dist; \
94  if ( segmentidxptr ) \
95  *segmentidxptr = idx; \
96  if ( fractionptr ) \
97  *fractionptr = frac; \
98  }
99 
100 template <class T> inline
101 double PolyLineND<T>::distTo( const T& pt, int* segmentidxptr,
102  double* fractionptr ) const
103 {
104  double mindist = MAXDOUBLE;
105 
106  for ( int idx=0; idx<this->size(); idx++ )
107  {
108  const int idy = nextIdx( idx );
109  if ( mIsUdf(idy) )
110  continue;
111 
112  const double a2 = pt.sqDistTo( (*this)[idx] );
113  const double b2 = pt.sqDistTo( (*this)[idy] );
114  const double c2 = (*this)[idx].sqDistTo( (*this)[idy] );
115 
116  if ( c2<=0.0 || b2>=a2+c2 )
117  {
118  const double a = Math::Sqrt( a2 );
119  mUpdateMinDist( a, idx, 0.0 );
120  }
121  else if ( a2 >= b2+c2 )
122  {
123  const double b = Math::Sqrt( b2 );
124  mUpdateMinDist( b, idx, 1.0 );
125  }
126  else
127  {
128  const double c = Math::Sqrt( c2 );
129  const double d = (a2+c2-b2) / (2*c);
130  const double h = (a2-d*d)>0 ? Math::Sqrt(a2-d*d) : 0.0;
131  mUpdateMinDist( h, idx, d/c );
132  }
133  }
134 
135  return mindist==MAXDOUBLE ? mUdf(double) : mindist;
136 }
137 
138 
139 template <class T> inline
140 T PolyLineND<T>::closestPoint( const T& pt ) const
141 {
142  int idx = 0;
143  double frac = 0;
144  if ( mIsUdf( distTo(pt,&idx,&frac) ) )
145  return T::udf();
146 
147  const int idy = nextIdx( idx );
148  if ( mIsUdf(idy) )
149  return T::udf();
150 
151  return (*this)[idx]*(1.0-frac) + (*this)[idy]*frac;
152 }
153 
154 
155 template <class T> inline
156 double PolyLineND<T>::arcLength( int index, double frac ) const
157 {
158  if ( index<0 || index>=this->size() || frac<0.0 || frac>1.0 )
159  return mUdf(double);
160 
161  double arclen = 0.0;
162 
163  for ( int idx=0; idx<=index; idx++ )
164  {
165  const int idy = nextIdx( idx );
166  if ( mIsUdf(idy) )
167  continue;
168 
169  const double len = (*this)[idx].distTo( (*this)[idy] );
170  if ( idx==index )
171  return arclen + len * frac;
172 
173  arclen += len;
174  }
175 
176  return arclen;
177 }
178 
179 
180 template <class T> inline
181 double PolyLineND<T>::arcLength( const T& pt ) const
182 {
183  int idx = 0;
184  double frac = 0;
185  if ( mIsUdf( distTo(pt,&idx,&frac) ) )
186  return mUdf(double);
187 
188  return arcLength( idx, frac );
189 }
190 
191 
192 template <class T> inline
194 {
195  return arcLength( this->size()-1, 1.0 );
196 }
197 
198 
199 template <class T> inline
200 T PolyLineND<T>::getPoint( int idx, double frac ) const
201 {
202  if ( idx<0 || idx>=this->size() || frac<0.0 || frac>1.0 )
203  return T::udf();
204 
205  if ( frac == 0.0 )
206  return (*this)[idx];
207 
208  if ( frac==1.0 && !(*this)[idx].isDefined() )
209  return getPoint( idx+1, 0.0 );
210 
211  const int idy = nextIdx( idx );
212  if ( mIsUdf(idy) )
213  return T::udf();
214 
215  return (*this)[idx]*(1.0-frac) + (*this)[idy]*frac;
216 }
217 
218 
219 template <class T> inline
220 T PolyLineND<T>::getPoint( double arclen ) const
221 {
222  if ( arclen<0.0 )
223  return T::udf();
224 
225  for ( int idx=0; idx<this->size(); idx++ )
226  {
227  const int idy = nextIdx( idx );
228  if ( mIsUdf(idy) )
229  continue;
230 
231  const double len = (*this)[idx].distTo( (*this)[idy] );
232  if ( arclen <= len )
233  {
234  const double frac = arclen / len;
235  return (*this)[idx]*(1.0-frac) + (*this)[idy]*frac;
236  }
237 
238  arclen -= len;
239  }
240 
241  return T::udf();
242 }
243 
244 
245 #endif
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:287
bool closed_
Definition: polylinend.h:53
#define mUpdateMinDist(dist, idx, frac)
Point-to-segment distance:
Definition: polylinend.h:90
T closestPoint(const T &pt) const
Definition: polylinend.h:140
PolyLineND(bool closed=false)
Definition: polylinend.h:28
Set of (small) copyable elements.
Definition: commontypes.h:30
double arcLength() const
Definition: polylinend.h:193
#define mUdf(type)
Use this macro to get the undefined for simple types.
Definition: undefval.h:272
(Closed) sequence(s) of connected n-D coordinates. Undefined coordinates separate consecutive sequenc...
Definition: polylinend.h:25
T getPoint(int idx, double frac=0.0) const
Definition: polylinend.h:200
bool isClosed() const
Definition: polylinend.h:36
double distTo(const T &pt, int *segmentidxptr=0, double *fractionptr=0) const
Definition: polylinend.h:101
int nextIdx(int) const
Definition: polylinend.h:58
#define MAXDOUBLE
Definition: commondefs.h:107
#define mClass(module)
Definition: commondefs.h:164
PolyLineND(const TypeSet< T > &coords, bool closed=false)
Definition: polylinend.h:31
float Sqrt(float)
void setClosed(bool yn)
Definition: polylinend.h:35

Generated at for the OpendTect seismic interpretation project. Copyright (C): dGB Beheer B. V. 2019