GteIntpBilinear2.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
10 #include <LowLevel/GteLogger.h>
11 
12 // The interpolator is for uniformly spaced (x,y)-values. The input samples
13 // F must be stored in row-major order to represent f(x,y); that is,
14 // F[c + xBound*r] corresponds to f(x,y), where c is the index corresponding
15 // to x and r is the index corresponding to y.
16 
17 namespace gte
18 {
19 
20 template <typename Real>
22 {
23 public:
24  // Construction.
25  IntpBilinear2(int xBound, int yBound, Real xMin, Real xSpacing,
26  Real yMin, Real ySpacing, Real const* F);
27 
28  // Member access.
29  inline int GetXBound() const;
30  inline int GetYBound() const;
31  inline int GetQuantity() const;
32  inline Real const* GetF() const;
33  inline Real GetXMin() const;
34  inline Real GetXMax() const;
35  inline Real GetXSpacing() const;
36  inline Real GetYMin() const;
37  inline Real GetYMax() const;
38  inline Real GetYSpacing() const;
39 
40  // Evaluate the function and its derivatives. The functions clamp the
41  // inputs to xmin <= x <= xmax and ymin <= y <= ymax. The first operator
42  // is for function evaluation. The second operator is for function or
43  // derivative evaluations. The xOrder argument is the order of the
44  // x-derivative and the yOrder argument is the order of the y-derivative.
45  // Both orders are zero to get the function value itself.
46  Real operator()(Real x, Real y) const;
47  Real operator()(int xOrder, int yOrder, Real x, Real y) const;
48 
49 private:
53  Real const* mF;
54  Real mBlend[2][2];
55 };
56 
57 
58 template <typename Real>
59 IntpBilinear2<Real>::IntpBilinear2(int xBound, int yBound, Real xMin,
60  Real xSpacing, Real yMin, Real ySpacing, Real const* F)
61  :
62  mXBound(xBound),
63  mYBound(yBound),
64  mQuantity(xBound * yBound),
65  mXMin(xMin),
66  mXSpacing(xSpacing),
67  mYMin(yMin),
68  mYSpacing(ySpacing),
69  mF(F)
70 {
71  // At least a 2x2 block of data points are needed.
72  LogAssert(mXBound >= 2 && mYBound >= 2 && mF, "Invalid input.");
73  LogAssert(mXSpacing > (Real)0 && mYSpacing > (Real)0, "Invalid input.");
74 
75  mXMax = mXMin + mXSpacing * static_cast<Real>(mXBound - 1);
76  mInvXSpacing = ((Real)1) / mXSpacing;
77  mYMax = mYMin + mYSpacing * static_cast<Real>(mYBound - 1);
78  mInvYSpacing = ((Real)1) / mYSpacing;
79 
80  mBlend[0][0] = (Real)1;
81  mBlend[0][1] = (Real)-1;
82  mBlend[1][0] = (Real)0;
83  mBlend[1][1] = (Real)1;
84 }
85 
86 template <typename Real> inline
88 {
89  return mXBound;
90 }
91 
92 template <typename Real> inline
94 {
95  return mYBound;
96 }
97 
98 template <typename Real> inline
100 {
101  return mQuantity;
102 }
103 
104 template <typename Real> inline
105 Real const* IntpBilinear2<Real>::GetF() const
106 {
107  return mF;
108 }
109 
110 template <typename Real> inline
112 {
113  return mXMin;
114 }
115 
116 template <typename Real> inline
118 {
119  return mXMax;
120 }
121 
122 template <typename Real> inline
124 {
125  return mXSpacing;
126 }
127 
128 template <typename Real> inline
130 {
131  return mYMin;
132 }
133 
134 template <typename Real> inline
136 {
137  return mYMax;
138 }
139 
140 template <typename Real> inline
142 {
143  return mYSpacing;
144 }
145 
146 template <typename Real>
147 Real IntpBilinear2<Real>::operator()(Real x, Real y) const
148 {
149  // Compute x-index and clamp to image.
150  Real xIndex = (x - mXMin) * mInvXSpacing;
151  int ix = static_cast<int>(xIndex);
152  if (ix < 0)
153  {
154  ix = 0;
155  }
156  else if (ix >= mXBound)
157  {
158  ix = mXBound - 1;
159  }
160 
161  // Compute y-index and clamp to image.
162  Real yIndex = (y - mYMin) * mInvYSpacing;
163  int iy = static_cast<int>(yIndex);
164  if (iy < 0)
165  {
166  iy = 0;
167  }
168  else if (iy >= mYBound)
169  {
170  iy = mYBound - 1;
171  }
172 
173  Real U[2];
174  U[0] = (Real)1;
175  U[1] = xIndex - ix;
176 
177  Real V[2];
178  V[0] = (Real)1.0;
179  V[1] = yIndex - iy;
180 
181  // Compute P = M*U and Q = M*V.
182  Real P[2], Q[2];
183  for (int row = 0; row < 2; ++row)
184  {
185  P[row] = (Real)0;
186  Q[row] = (Real)0;
187  for (int col = 0; col < 2; ++col)
188  {
189  P[row] += mBlend[row][col] * U[col];
190  Q[row] += mBlend[row][col] * V[col];
191  }
192  }
193 
194  // Compute (M*U)^t D (M*V) where D is the 2x2 subimage containing (x,y).
195  Real result = (Real)0;
196  for (int row = 0; row < 2; ++row)
197  {
198  int yClamp = iy + row;
199  if (yClamp >= mYBound)
200  {
201  yClamp = mYBound - 1;
202  }
203 
204  for (int col = 0; col < 2; ++col)
205  {
206  int xClamp = ix + col;
207  if (xClamp >= mXBound)
208  {
209  xClamp = mXBound - 1;
210  }
211 
212  result += P[col] * Q[row] * mF[xClamp + mXBound * yClamp];
213  }
214  }
215 
216  return result;
217 }
218 
219 template <typename Real>
220 Real IntpBilinear2<Real>::operator()(int xOrder, int yOrder, Real x, Real y)
221 const
222 {
223  // Compute x-index and clamp to image.
224  Real xIndex = (x - mXMin) * mInvXSpacing;
225  int ix = static_cast<int>(xIndex);
226  if (ix < 0)
227  {
228  ix = 0;
229  }
230  else if (ix >= mXBound)
231  {
232  ix = mXBound - 1;
233  }
234 
235  // Compute y-index and clamp to image.
236  Real yIndex = (y - mYMin) * mInvYSpacing;
237  int iy = static_cast<int>(yIndex);
238  if (iy < 0)
239  {
240  iy = 0;
241  }
242  else if (iy >= mYBound)
243  {
244  iy = mYBound - 1;
245  }
246 
247  Real U[2], dx, xMult;
248  switch (xOrder)
249  {
250  case 0:
251  dx = xIndex - ix;
252  U[0] = (Real)1;
253  U[1] = dx;
254  xMult = (Real)1;
255  break;
256  case 1:
257  dx = xIndex - ix;
258  U[0] = (Real)0;
259  U[1] = (Real)1;
260  xMult = mInvXSpacing;
261  break;
262  default:
263  return (Real)0;
264  }
265 
266  Real V[2], dy, yMult;
267  switch (yOrder)
268  {
269  case 0:
270  dy = yIndex - iy;
271  V[0] = (Real)1;
272  V[1] = dy;
273  yMult = (Real)1;
274  break;
275  case 1:
276  dy = yIndex - iy;
277  V[0] = (Real)0;
278  V[1] = (Real)1;
279  yMult = mInvYSpacing;
280  break;
281  default:
282  return (Real)0;
283  }
284 
285  // Compute P = M*U and Q = M*V.
286  Real P[2], Q[2];
287  for (int row = 0; row < 2; ++row)
288  {
289  P[row] = (Real)0;
290  Q[row] = (Real)0;
291  for (int col = 0; col < 2; ++col)
292  {
293  P[row] += mBlend[row][col] * U[col];
294  Q[row] += mBlend[row][col] * V[col];
295  }
296  }
297 
298  // Compute (M*U)^t D (M*V) where D is the 2x2 subimage containing (x,y).
299  Real result = (Real)0;
300  for (int row = 0; row < 2; ++row)
301  {
302  int yClamp = iy + row;
303  if (yClamp >= mYBound)
304  {
305  yClamp = mYBound - 1;
306  }
307 
308  for (int col = 0; col < 2; ++col)
309  {
310  int xClamp = ix + col;
311  if (xClamp >= mXBound)
312  {
313  xClamp = mXBound - 1;
314  }
315 
316  result += P[col] * Q[row] * mF[xClamp + mXBound * yClamp];
317  }
318  }
319  result *= xMult * yMult;
320 
321  return result;
322 }
323 
324 
325 }
Real GetYSpacing() const
int GetYBound() const
#define LogAssert(condition, message)
Definition: GteLogger.h:86
Real GetXMax() const
IntpBilinear2(int xBound, int yBound, Real xMin, Real xSpacing, Real yMin, Real ySpacing, Real const *F)
int GetQuantity() const
GLint GLenum GLint x
Definition: glcorearb.h:404
Real GetYMin() const
GLenum GLenum GLsizei void * row
Definition: glext.h:2725
Real const * GetF() const
int GetXBound() const
Real GetXSpacing() const
Real GetYMax() const
GLuint64EXT * result
Definition: glext.h:10003
GLint y
Definition: glcorearb.h:98
Real GetXMin() const
Real operator()(Real x, Real y) const


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:00