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

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