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

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