OpendTect-6_4  6.4
interpol2d.h
Go to the documentation of this file.
1 #ifndef interpol2d_h
2 #define interpol2d_h
3 
4 /*
5 ________________________________________________________________________
6 
7  (C) dGB Beheer B.V.; (LICENSE) http://opendtect.org/OpendTect_license.txt
8  Author: Bert
9  Date: Mar 2006
10  RCS: $Id$
11 ________________________________________________________________________
12 
13 */
14 
15 #include "interpol1d.h"
16 
17 namespace Interpolate
18 {
19 
44 template <class T>
46 {
47 public:
48  virtual ~Applier2D() {}
49  virtual void set(const T*) = 0;
50  virtual T apply(float x,float y) const = 0;
51 };
52 
53 
58 template <class T>
59 mClass(Algo) LinearReg2D : public Applier2D<T>
60 {
61 public:
62 
63  inline LinearReg2D();
64  inline LinearReg2D(const T*);
65  inline LinearReg2D(T v00,T v10,T v01,T v11);
66 
67  inline void set(const T*);
68  inline void set(T v00,T v01,T v10,T v11);
69  inline T apply(float x,float y) const;
70 
71 protected:
72 
73  T a_[4];
74 };
75 
76 
77 template <class T>
78 inline T linearReg2D( T v00, T v01, T v10, T v11, float x, float y )
79 { return LinearReg2D<T>( v00, v01, v10, v11 ).apply ( x, y ); }
80 
81 
86 template <class T>
88 {
89 public:
90 
91  inline LinearReg2DWithUdf();
92  inline LinearReg2DWithUdf(const T*);
93  inline LinearReg2DWithUdf(T v00,T v10,T v01,T v11);
94 
95  inline void set(const T*);
96  inline void set(T v00,T v01,T v10,T v11);
97  inline T apply(float x,float y) const;
98 
99 protected:
100 
102  bool haveudf_;
103  bool u00_;
104  bool u10_;
105  bool u01_;
106  bool u11_;
107 };
108 
109 
110 template <class T>
111 inline T linearReg2DWithUdf( T v00, T v01, T v10, T v11, float x, float y )
112 {
113  return LinearReg2DWithUdf<T>( v00, v01, v10, v11 ).apply( x, y );
114 }
115 
116 
125 template <class T>
126 mClass(Algo) PolyReg2D : public Applier2D<T>
127 {
128 public:
129 
130  inline PolyReg2D(float xstretch=1);
131  inline PolyReg2D(const T*,float xstretch=1);
132  inline PolyReg2D(T vm10,T vm11,
133  T v0m1,T v00, T v01,T v02,
134  T v1m1,T v10, T v11,T v12,
135  T v20, T v21, float xstretch=1);
136 
137  inline void set(const T*);
138  inline void set( T vm10,T vm11,
139  T v0m1,T v00, T v01, T v02,
140  T v1m1,T v10, T v11, T v12,
141  T v20, T v21);
142 
143  inline T apply(float x,float y) const;
144 
145 protected:
146 
147  PolyReg1D<T> ix0_, ix1_, iy0_, iy1_;
148  T vm10_, v0m1_, v20_, v02_;
149  T delxm1_, delym1_, delx2_, dely2_;
150  float xs_;
151 
152 };
153 
154 
155 template <class T>
156 inline T polyReg2D( T vm10, T vm11, T v0m1, T v00, T v01, T v02,
157  T v1m1, T v10, T v11, T v12, T v20, T v21, float x, float y,
158  float xs=1 )
159 {
160  return PolyReg2D<T>(vm10,vm11,v0m1,v00,v01,v02,v1m1,v10,v11,v12,v20,v21,xs)
161  .apply( x, y );
162 }
163 
164 
173 template <class T>
175 {
176 public:
177 
178  inline PolyReg2DWithUdf(float xstretch=1);
179  inline PolyReg2DWithUdf(const T*,float xstretch=1);
180  inline PolyReg2DWithUdf(T vm10,T vm11,T v0m1,T v00,T v01,T v02,
181  T v1m1,T v10,T v11,T v12,T v20,T v21,
182  float xstretch=1);
183 
184  inline void set(const T*);
185  inline void set( T vm10,T vm11,
186  T v0m1,T v00, T v01, T v02,
187  T v1m1,T v10, T v11, T v12,
188  T v20, T v21);
189 
190  inline T apply(float x,float y) const;
191 
192 protected:
193 
194  inline void fillOuter2Inner(T,T,T,T,T,T,T,T,T&,T&,T&,T&);
195  inline void fillInner2Inner(T&,T&,T&,T&);
196  inline void fillInner2Outer(T,T,T,T,T&,T&,T&,T&,T&,T&,T&,T&);
197 
199  bool haveudf_;
200  bool u00_;
201  bool u10_;
202  bool u01_;
203  bool u11_;
204  bool um10_;
205  bool um11_;
206  bool u0m1_;
207  bool u02_;
208  bool u1m1_;
209  bool u12_;
210  bool u20_;
211  bool u21_;
212 
213 };
214 
215 
216 template <class T>
217 inline T polyReg2DWithUdf( T vm10, T vm11, T v0m1, T v00, T v01, T v02,
218  T v1m1, T v10, T v11, T v12, T v20, T v21, float x, float y )
219 {
220  return PolyReg2DWithUdf<T>(vm10,vm11,v0m1,v00,v01,v02,v1m1,v10,v11,v12,v20,
221  v21).apply( x, y );
222 }
223 
224 //--- LinearReg2D Implementation
225 
226 template <class T> inline
228 
229 
230 template <class T> inline
232 {
233  set( v[0], v[1], v[2], v[3] );
234 }
235 
236 
237 template <class T> inline
238 LinearReg2D<T>::LinearReg2D( T v00, T v01, T v10, T v11 )
239 {
240  set( v00, v01, v10, v11 );
241 }
242 
243 
244 template <class T> inline
245 void LinearReg2D<T>::set( const T* v )
246 {
247  set( v[0], v[1], v[2], v[3] );
248 }
249 
250 
251 template <class T> inline
252 void LinearReg2D<T>::set( T v00, T v01, T v10, T v11 )
253 {
254  a_[0] = v00;
255  a_[1] = v10 - v00;
256  a_[2] = v01 - v00;
257  a_[3] = v11 + v00 - v10 - v01;
258 }
259 
260 
261 template <class T> inline
262 T LinearReg2D<T>::apply( float x, float y ) const
263 {
264  return a_[0] + a_[1] * x + a_[2] * y + a_[3] * x * y;
265 }
266 
267 
268 //--- LinearReg2DWithUdf Implementation
269 
270 template <class T> inline
272 
273 
274 template <class T> inline
276 {
277  set( v[0], v[1], v[2], v[3] );
278 }
279 
280 
281 template <class T> inline
282 LinearReg2DWithUdf<T>::LinearReg2DWithUdf( T v00, T v01, T v10, T v11 )
283 {
284  set( v00, v01, v10, v11 );
285 }
286 
287 
288 template <class T> inline
289 void LinearReg2DWithUdf<T>::set( const T* v )
290 {
291  set( v[0], v[1], v[2], v[3] );
292 }
293 
294 
295 #define mFillIfUdfFromSquare(nd,left,right,opp) \
296  if ( u##nd##_ ) \
297  { \
298  if ( u##left##_ && u##right##_ ) \
299  v##nd = v##opp; \
300  else \
301  v##nd = u##left##_ || u##right##_ ? \
302  (u##right##_ ? v##left : v##right) \
303  : (v##left + v##right) / 2; \
304  }
305 
306 template <class T> inline
307 void LinearReg2DWithUdf<T>::set( T v00, T v01, T v10, T v11 )
308 {
309  u00_ = mIsUdf(v00);
310  u10_ = mIsUdf(v10);
311  u01_ = mIsUdf(v01);
312  u11_ = mIsUdf(v11);
313  haveudf_ = u00_ || u10_ || u01_ || u11_;
314 
315  if ( haveudf_ )
316  {
317  mFillIfUdfFromSquare(00,01,10,11)
318  mFillIfUdfFromSquare(10,00,11,01)
319  mFillIfUdfFromSquare(01,11,00,10)
320  mFillIfUdfFromSquare(11,10,01,00)
321  }
322 
323  intp_.set( v00, v01, v10, v11 );
324 }
325 
326 
327 #define mRetUdfIfNearestUdf() \
328  if ( haveudf_ && ( \
329  ( u00_ && x < 0.5 && y < 0.5 ) \
330  || ( u10_ && x >= 0.5 && y < 0.5 ) \
331  || ( u01_ && x < 0.5 && y >= 0.5 ) \
332  || ( u11_ && x >= 0.5 && y >= 0.5 ) ) ) \
333  return mUdf(T)
334 
335 
336 
337 template <class T> inline
338 T LinearReg2DWithUdf<T>::apply( float x, float y ) const
339 {
341 
342  return intp_.apply( x, y );
343 }
344 
345 
346 //--- PolyReg2D Implementation
347 
348 
349 template <class T> inline
351  : xs_(xs)
352 {}
353 
354 
355 template <class T> inline
356 PolyReg2D<T>::PolyReg2D( const T* v, float xs )
357  : xs_(xs)
358 {
359  set( v );
360 }
361 
362 
363 template <class T> inline
364 PolyReg2D<T>::PolyReg2D( T vm10, T vm11,
365  T v0m1, T v00, T v01, T v02,
366  T v1m1, T v10, T v11, T v12,
367  T v20, T v21, float xs )
368  : xs_(xs)
369 {
370  set( vm10, vm11, v0m1, v00, v01, v02, v1m1, v10, v11, v12, v20, v21 );
371 }
372 
373 
374 template <class T> inline
375 void PolyReg2D<T>::set( const T* v )
376 {
377  if ( !mIsUdf(-v[4]) )
378  set( v[4], v[5], v[6], v[0], v[1], v[7], v[8], v[2], v[3],
379  v[9], v[10], v[11] );
380  else
381  set( v[0], v[1], v[0], v[0], v[1], v[1], v[2], v[2], v[3],
382  v[3], v[2], v[3] );
383 }
384 
385 
386 template <class T> inline
387 void PolyReg2D<T>::set( T vm10, T vm11,
388  T v0m1, T v00, T v01, T v02,
389  T v1m1, T v10, T v11, T v12,
390  T v20, T v21 )
391 {
392  vm10_ = vm10; v0m1_ = v0m1; v20_ = v20; v02_ = v02;
393  delxm1_ = vm11 - vm10; delym1_ = v1m1 - v0m1;
394  delx2_ = v21 - v20; dely2_ = v12 - v02;
395  ix0_.set( v0m1, v00, v01, v02 ); ix1_.set( v1m1, v10, v11, v12 );
396  iy0_.set( vm10, v00, v10, v20 ); iy1_.set( vm11, v01, v11, v21 );
397 }
398 
399 
400 template <class T> inline
401 T PolyReg2D<T>::apply( float x, float y ) const
402 {
403  // Exactly on border or outside: handle now
404  if ( x <= 0 ) return ix0_.apply( y );
405  else if ( y <= 0 ) return iy0_.apply( x );
406  else if ( x >= 1 ) return ix1_.apply( y );
407  else if ( y >= 1 ) return iy1_.apply( x );
408 
409  // Values on X-line through point
410  const T vxm1 = vm10_ + delxm1_ * y;
411  const T vx0 = ix0_.apply( y );
412  const T vx1 = ix1_.apply( y );
413  const T vx2 = v20_ + delx2_ * y;
414 
415  // Values on Y-line through point
416  const T vym1 = v0m1_ + delym1_ * x;
417  const T vy0 = iy0_.apply( x );
418  const T vy1 = iy1_.apply( x );
419  const T vy2 = v02_ + dely2_ * x;
420 
421  // Result is weighted average, weight dep on distance from border
422  const T estx = polyReg1D( vxm1, vx0, vx1, vx2, x );
423  const T esty = polyReg1D( vym1, vy0, vy1, vy2, y );
424  const float distfromedgex = x > 0.5 ? 1 - x : x;
425  const float distfromedgey = y > 0.5 ? 1 - y : y;
426  // wtx == distfromedgey;
427  const float wty = distfromedgex * xs_;
428  return (distfromedgey * estx + wty * esty) / (distfromedgey + wty);
429 }
430 
431 
432 
433 //--- PolyReg2DWithUdf Implementation
434 
435 template <class T> inline
437  : intp_(xs)
438 {
439 }
440 
441 
442 template <class T> inline
444  : intp_(xs)
445 {
446  set( v );
447 }
448 
449 
450 template <class T> inline
451 PolyReg2DWithUdf<T>::PolyReg2DWithUdf( T vm10,T vm11,T v0m1,T v00,T v01, T v02,
452  T v1m1,T v10, T v11, T v12, T v20,T v21,
453  float xs )
454  : intp_(xs)
455 {
456  set( vm10, vm11, v0m1, v00, v01, v02, v1m1, v10, v11, v12, v20, v21 );
457 }
458 
459 
460 template <class T> inline
461 void PolyReg2DWithUdf<T>::set( const T* v )
462 {
463  if ( !mIsUdf(-v[4]) )
464  set( v[4], v[5], v[6], v[0], v[1], v[7], v[8], v[2], v[3],
465  v[9], v[10], v[11] );
466  else
467  set( v[0], v[1], v[0], v[0], v[1], v[1], v[2], v[2], v[3],
468  v[3], v[2], v[3] );
469 }
470 
471 
472 template <class T> inline
473 void PolyReg2DWithUdf<T>::fillOuter2Inner( T vm10, T vm11, T v0m1, T v02,
474  T v1m1, T v12, T v20, T v21,
475  T& v00, T& v01, T& v10, T& v11 )
476 {
477 #define mFillWithEither(nd,cand1,cand2) \
478  if ( u##nd##_ ) \
479  { \
480  if ( !u##cand1##_ ) v##nd = v##cand1; \
481  else if ( !u##cand2##_ ) v##nd = v##cand2; \
482  }
483 
484  mFillWithEither(00,m10,0m1)
485  mFillWithEither(10,1m1,20)
486  mFillWithEither(11,21,12)
487  mFillWithEither(01,02,m11)
488 
489 #undef mFillWithEither
490 }
491 
492 
493 template <class T> inline
494 void PolyReg2DWithUdf<T>::fillInner2Inner( T& v00, T& v01, T& v10, T& v11 )
495 {
496  bool kpu00 = u00_, kpu10 = u10_, kpu01 = u01_, kpu11 = u11_;
497  u00_ = mIsUdf(v00); u10_ = mIsUdf(v10);
498  u01_ = mIsUdf(v01); u11_ = mIsUdf(v11);
499  if ( u00_ || u10_ || u01_ || u11_ )
500  {
501  mFillIfUdfFromSquare(00,01,10,11)
502  mFillIfUdfFromSquare(10,00,11,01)
503  mFillIfUdfFromSquare(01,11,00,10)
504  mFillIfUdfFromSquare(11,10,01,00)
505  }
506  u00_ = kpu00; u10_ = kpu10; u01_ = kpu01; u11_ = kpu11;
507 }
508 
509 
510 template <class T> inline
511 void PolyReg2DWithUdf<T>::fillInner2Outer( T v00, T v01, T v10, T v11,
512  T& vm10, T& vm11, T& v0m1, T& v02,
513  T& v1m1, T& v12, T& v20, T& v21 )
514 {
515 #define mFillIfUdf(nd,src) if ( mIsUdf(v##nd) ) v##nd= v##src;
516  mFillIfUdf(m10,00);
517  mFillIfUdf(0m1,00);
518  mFillIfUdf(1m1,10);
519  mFillIfUdf(20,10);
520  mFillIfUdf(m11,01);
521  mFillIfUdf(02,01);
522  mFillIfUdf(12,11);
523  mFillIfUdf(21,11);
524 # undef mFillIfUdf
525 }
526 
527 
528 template <class T> inline
529 void PolyReg2DWithUdf<T>::set( T vm10, T vm11,
530  T v0m1, T v00, T v01, T v02,
531  T v1m1, T v10, T v11, T v12,
532  T v20, T v21 )
533 {
534  u00_ = mIsUdf(v00);
535  u10_ = mIsUdf(v10);
536  u01_ = mIsUdf(v01);
537  u11_ = mIsUdf(v11);
538  um10_ = mIsUdf(vm10);
539  um11_ = mIsUdf(vm11);
540  u0m1_ = mIsUdf(v0m1);
541  u1m1_ = mIsUdf(v1m1);
542  u02_ = mIsUdf(v02);
543  u12_ = mIsUdf(v12);
544  u20_ = mIsUdf(v20);
545  u21_ = mIsUdf(v21);
546  haveudf_ = u00_ || u10_ || u01_ || u11_;
547 
548  if ( haveudf_ || u02_ || u12_ || u20_ || u21_
549  || um10_ || um11_ || u0m1_ || u1m1_ )
550  {
551  if ( haveudf_ )
552  {
553  fillOuter2Inner( vm10, vm11, v0m1, v02, v1m1, v12, v20, v21,
554  v00, v01, v10, v11 );
555  fillInner2Inner( v00, v01, v10, v11 );
556  }
557  fillInner2Outer( v00, v01, v10, v11,
558  vm10, vm11, v0m1, v02, v1m1, v12, v20, v21 );
559  }
560 
561  intp_.set( vm10, vm11, v0m1, v00, v01, v02, v1m1, v10, v11, v12, v20, v21 );
562 }
563 
564 template <class T> inline
565 T PolyReg2DWithUdf<T>::apply( float x, float y ) const
566 {
568 
569  return intp_.apply( x, y );
570 }
571 
572 
573 #undef mFillIfUdfFromSquare
574 #undef mRetUdfIfNearestUdf
575 
576 
577 }// namespace Interpolate
578 
579 #endif
void fillOuter2Inner(T, T, T, T, T, T, T, T, T &, T &, T &, T &)
Definition: interpol2d.h:473
Definition: interpol1d.h:38
#define mIsUdf(val)
Use mIsUdf to check for undefinedness of simple types.
Definition: undefval.h:287
void fillInner2Inner(T &, T &, T &, T &)
Definition: interpol2d.h:494
T v0m1_
Definition: interpol2d.h:148
bool u01_
Definition: interpol2d.h:202
PolyReg1D< T > iy1_
Definition: interpol2d.h:147
PolyReg2DWithUdf(float xstretch=1)
Definition: interpol2d.h:436
void fillInner2Outer(T, T, T, T, T &, T &, T &, T &, T &, T &, T &, T &)
Definition: interpol2d.h:511
#define mFillWithEither(nd, cand1, cand2)
bool u20_
Definition: interpol2d.h:210
bool u0m1_
Definition: interpol2d.h:206
T apply(float x, float y) const
Definition: interpol2d.h:565
#define mFillIfUdf(nd, src)
bool um10_
Definition: interpol2d.h:204
Linear 2D interpolation.
Definition: interpol2d.h:59
#define mRetUdfIfNearestUdf()
Definition: interpol2d.h:327
T linearReg2D(T v00, T v01, T v10, T v11, float x, float y)
Definition: interpol2d.h:78
bool u10_
Definition: interpol2d.h:201
Definition: interpol1d.h:92
LinearReg2D()
Definition: interpol2d.h:227
bool u00_
Definition: interpol2d.h:200
T polyReg1D(T vm1, T v0, T v1, T v2, float x)
Definition: interpol1d.h:130
T v02_
Definition: interpol2d.h:148
bool u00_
Definition: interpol2d.h:103
void set(const T *)
Definition: interpol2d.h:461
T delxm1_
Definition: interpol2d.h:149
T linearReg2DWithUdf(T v00, T v01, T v10, T v11, float x, float y)
Definition: interpol2d.h:111
bool u12_
Definition: interpol2d.h:209
#define mFillIfUdfFromSquare(nd, left, right, opp)
Definition: interpol2d.h:295
PolyReg2D(float xstretch=1)
Definition: interpol2d.h:350
T delym1_
Definition: interpol2d.h:149
PolyReg1D< T > ix1_
Definition: interpol2d.h:147
bool um11_
Definition: interpol2d.h:205
void set(const T *)
Definition: interpol2d.h:375
bool haveudf_
Definition: interpol2d.h:199
T apply(float x, float y) const
Definition: interpol2d.h:338
virtual ~Applier2D()
Definition: interpol2d.h:48
void set(const T *)
Definition: interpol2d.h:245
T delx2_
Definition: interpol2d.h:149
void set(const T *)
Definition: interpol2d.h:289
bool u11_
Definition: interpol2d.h:106
T v20_
Definition: interpol2d.h:148
PolyReg2D< T > intp_
Definition: interpol2d.h:198
PolyReg1D< T > iy0_
Definition: interpol2d.h:147
T apply(float x, float y) const
Definition: interpol2d.h:262
bool u11_
Definition: interpol2d.h:203
T polyReg2D(T vm10, T vm11, T v0m1, T v00, T v01, T v02, T v1m1, T v10, T v11, T v12, T v20, T v21, float x, float y, float xs=1)
Definition: interpol2d.h:156
PolyReg1D< T > ix0_
Definition: interpol2d.h:147
bool u01_
Definition: interpol2d.h:105
Linear 2D interpolation with standard undef handling.
Definition: interpol2d.h:87
float xs_
Definition: interpol2d.h:150
bool u1m1_
Definition: interpol2d.h:208
Interpolate 2D regularly sampled, using a 2nd order surface.
Definition: interpol2d.h:126
bool haveudf_
Definition: interpol2d.h:102
bool u21_
Definition: interpol2d.h:211
specification for a 2D interpolator
Definition: interpol2d.h:45
T polyReg2DWithUdf(T vm10, T vm11, T v0m1, T v00, T v01, T v02, T v1m1, T v10, T v11, T v12, T v20, T v21, float x, float y)
Definition: interpol2d.h:217
bool u10_
Definition: interpol2d.h:104
#define mClass(module)
Definition: commondefs.h:164
T vm10_
Definition: interpol2d.h:148
T apply(float x, float y) const
Definition: interpol2d.h:401
T dely2_
Definition: interpol2d.h:149
PolyReg2D which smoothly handles undefined values.
Definition: interpol2d.h:174
LinearReg2D< T > intp_
Definition: interpol2d.h:101
bool u02_
Definition: interpol2d.h:207
LinearReg2DWithUdf()
Definition: interpol2d.h:271

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