sisi4s
Loading...
Searching...
No Matches
TrilinearInterpolation.hpp
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#ifndef TRILINEAR_INTERPOLATION_H
9#define TRILINEAR_INTERPOLATION_H
10
11// different assert routines in sisi4s
12#include <util/Exception.hpp>
13
14// The interpolator is for uniformly spaced(x,y z)-values. The input samples
15// must be stored in lexicographical order to represent f(x,y,z); that is,
16// F[c + xBound*(r + yBound*s)] corresponds to f(x,y,z), where c is the index
17// corresponding to x, r is the index corresponding to y, and s is the index
18// corresponding to z.
19
20namespace gte
21{
22
23template <typename Real>
25{
26public:
27 // Construction.
28 IntpTrilinear3(int xBound, int yBound, int zBound, Real xMin,
29 Real xSpacing, Real yMin, Real ySpacing, Real zMin, Real zSpacing,
30 Real const* F);
31
32 // Member access.
33 inline int GetXBound() const;
34 inline int GetYBound() const;
35 inline int GetZBound() const;
36 inline int GetQuantity() const;
37 inline Real const* GetF() const;
38 inline Real GetXMin() const;
39 inline Real GetXMax() const;
40 inline Real GetXSpacing() const;
41 inline Real GetYMin() const;
42 inline Real GetYMax() const;
43 inline Real GetYSpacing() const;
44 inline Real GetZMin() const;
45 inline Real GetZMax() const;
46 inline Real GetZSpacing() const;
47
48 // Evaluate the function and its derivatives. The functions clamp the
49 // inputs to xmin <= x <= xmax, ymin <= y <= ymax, and zmin <= z <= zmax.
50 // The first operator is for function evaluation. The second operator is
51 // for function or derivative evaluations. The xOrder argument is the
52 // order of the x-derivative, the yOrder argument is the order of the
53 // y-derivative, and the zOrder argument is the order of the z-derivative.
54 // All orders are zero to get the function value itself.
55 Real operator()(Real x, Real y, Real z) const;
56 Real operator()(int xOrder, int yOrder, int zOrder, Real x, Real y,
57 Real z) const;
58
59private:
60 int mXBound, mYBound, mZBound, mQuantity;
61 Real mXMin, mXMax, mXSpacing, mInvXSpacing;
62 Real mYMin, mYMax, mYSpacing, mInvYSpacing;
63 Real mZMin, mZMax, mZSpacing, mInvZSpacing;
64 Real const* mF;
65 Real mBlend[2][2];
66};
67
68
69template <typename Real>
70IntpTrilinear3<Real>::IntpTrilinear3(int xBound, int yBound, int zBound,
71 Real xMin, Real xSpacing, Real yMin, Real ySpacing, Real zMin,
72 Real zSpacing, Real const* F)
73 :
74 mXBound(xBound),
75 mYBound(yBound),
76 mZBound(zBound),
77 mQuantity(xBound * yBound * zBound),
78 mXMin(xMin),
79 mXSpacing(xSpacing),
80 mYMin(yMin),
81 mYSpacing(ySpacing),
82 mZMin(zMin),
83 mZSpacing(zSpacing),
84 mF(F)
85{
86 // At least a 2x2x2 block of data points are needed to construct the
87 // trilinear interpolation.
88 Assert(mXBound >= 2 && mYBound >= 2 && mZBound >= 2 && mF,
89 "Invalid input.");
90 Assert(mXSpacing > (Real)0 && mYSpacing > (Real)0 &&
91 mZSpacing > (Real)0, "Invalid input.");
92
93 mXMax = mXMin + mXSpacing * static_cast<Real>(mXBound - 1);
94 mInvXSpacing = ((Real)1) / mXSpacing;
95 mYMax = mYMin + mYSpacing * static_cast<Real>(mYBound - 1);
96 mInvYSpacing = ((Real)1) / mYSpacing;
97 mZMax = mZMin + mZSpacing * static_cast<Real>(mZBound - 1);
98 mInvZSpacing = ((Real)1) / mZSpacing;
99
100 mBlend[0][0] = (Real)1;
101 mBlend[0][1] = (Real)-1;
102 mBlend[1][0] = (Real)0;
103 mBlend[1][1] = (Real)1;
104}
105
106template <typename Real> inline
108{
109 return mXBound;
110}
111
112template <typename Real> inline
114{
115 return mYBound;
116}
117
118template <typename Real> inline
120{
121 return mZBound;
122}
123
124template <typename Real> inline
126{
127 return mQuantity;
128}
129
130template <typename Real> inline
131Real const* IntpTrilinear3<Real>::GetF() const
132{
133 return mF;
134}
135
136template <typename Real> inline
138{
139 return mXMin;
140}
141
142template <typename Real> inline
144{
145 return mXMax;
146}
147
148template <typename Real> inline
150{
151 return mXSpacing;
152}
153
154template <typename Real> inline
156{
157 return mYMin;
158}
159
160template <typename Real> inline
162{
163 return mYMax;
164}
165
166template <typename Real> inline
168{
169 return mYSpacing;
170}
171
172template <typename Real> inline
174{
175 return mZMin;
176}
177
178template <typename Real> inline
180{
181 return mZMax;
182}
183
184template <typename Real> inline
186{
187 return mZSpacing;
188}
189
190template <typename Real>
191Real IntpTrilinear3<Real>::operator()(Real x, Real y, Real z) const
192{
193 // Compute x-index and clamp to image.
194 Real xIndex = (x - mXMin) * mInvXSpacing;
195 int ix = static_cast<int>(xIndex);
196 if (ix < 0)
197 {
198 ix = 0;
199 }
200 else if (ix >= mXBound)
201 {
202 ix = mXBound - 1;
203 }
204
205 // Compute y-index and clamp to image.
206 Real yIndex = (y - mYMin) * mInvYSpacing;
207 int iy = static_cast<int>(yIndex);
208 if (iy < 0)
209 {
210 iy = 0;
211 }
212 else if (iy >= mYBound)
213 {
214 iy = mYBound - 1;
215 }
216
217 // Compute z-index and clamp to image.
218 Real zIndex = (z - mZMin) * mInvZSpacing;
219 int iz = static_cast<int>(zIndex);
220 if (iz < 0)
221 {
222 iz = 0;
223 }
224 else if (iz >= mZBound)
225 {
226 iz = mZBound - 1;
227 }
228
229 Real U[2];
230 U[0] = (Real)1;
231 U[1] = xIndex - ix;
232
233 Real V[2];
234 V[0] = (Real)1;
235 V[1] = yIndex - iy;
236
237 Real W[2];
238 W[0] = (Real)1;
239 W[1] = zIndex - iz;
240
241 // Compute P = M*U, Q = M*V, R = M*W.
242 Real P[2], Q[2], R[2];
243 for (int row = 0; row < 2; ++row)
244 {
245 P[row] = (Real)0;
246 Q[row] = (Real)0;
247 R[row] = (Real)0;
248 for (int col = 0; col < 2; ++col)
249 {
250 P[row] += mBlend[row][col] * U[col];
251 Q[row] += mBlend[row][col] * V[col];
252 R[row] += mBlend[row][col] * W[col];
253 }
254 }
255
256 // compute the tensor product (M*U)(M*V)(M*W)*D where D is the 2x2x2
257 // subimage containing (x,y,z)
258 Real result = (Real)0;
259 for (int slice = 0; slice < 2; ++slice)
260 {
261 int zClamp = iz + slice;
262 if (zClamp >= mZBound)
263 {
264 zClamp = mZBound - 1;
265 }
266
267 for (int row = 0; row < 2; ++row)
268 {
269 int yClamp = iy + row;
270 if (yClamp >= mYBound)
271 {
272 yClamp = mYBound - 1;
273 }
274
275 for (int col = 0; col < 2; ++col)
276 {
277 int xClamp = ix + col;
278 if (xClamp >= mXBound)
279 {
280 xClamp = mXBound - 1;
281 }
282
283 result += P[col] * Q[row] * R[slice] *
284 mF[xClamp + mXBound * (yClamp + mYBound * zClamp)];
285 }
286 }
287 }
288
289 return result;
290}
291
292template <typename Real>
293Real IntpTrilinear3<Real>::operator()(int xOrder, int yOrder, int zOrder,
294 Real x, Real y, Real z) const
295{
296 // Compute x-index and clamp to image.
297 Real xIndex = (x - mXMin) * mInvXSpacing;
298 int ix = static_cast<int>(xIndex);
299 if (ix < 0)
300 {
301 ix = 0;
302 }
303 else if (ix >= mXBound)
304 {
305 ix = mXBound - 1;
306 }
307
308 // Compute y-index and clamp to image.
309 Real yIndex = (y - mYMin) * mInvYSpacing;
310 int iy = static_cast<int>(yIndex);
311 if (iy < 0)
312 {
313 iy = 0;
314 }
315 else if (iy >= mYBound)
316 {
317 iy = mYBound - 1;
318 }
319
320 // Compute z-index and clamp to image.
321 Real zIndex = (z - mZMin) * mInvZSpacing;
322 int iz = static_cast<int>(zIndex);
323 if (iz < 0)
324 {
325 iz = 0;
326 }
327 else if (iz >= mZBound)
328 {
329 iz = mZBound - 1;
330 }
331
332 Real U[2], dx, xMult;
333 switch (xOrder)
334 {
335 case 0:
336 dx = xIndex - ix;
337 U[0] = (Real)1;
338 U[1] = dx;
339 xMult = (Real)1;
340 break;
341 case 1:
342 dx = xIndex - ix;
343 U[0] = (Real)0;
344 U[1] = (Real)1;
345 xMult = mInvXSpacing;
346 break;
347 default:
348 return (Real)0;
349 }
350
351 Real V[2], dy, yMult;
352 switch (yOrder)
353 {
354 case 0:
355 dy = yIndex - iy;
356 V[0] = (Real)1;
357 V[1] = dy;
358 yMult = (Real)1;
359 break;
360 case 1:
361 dy = yIndex - iy;
362 V[0] = (Real)0;
363 V[1] = (Real)1;
364 yMult = mInvYSpacing;
365 break;
366 default:
367 return (Real)0;
368 }
369
370 Real W[2], dz, zMult;
371 switch (zOrder)
372 {
373 case 0:
374 dz = zIndex - iz;
375 W[0] = (Real)1;
376 W[1] = dz;
377 zMult = (Real)1;
378 break;
379 case 1:
380 dz = zIndex - iz;
381 W[0] = (Real)0;
382 W[1] = (Real)1;
383 zMult = mInvZSpacing;
384 break;
385 default:
386 return (Real)0;
387 }
388
389 // Compute P = M*U, Q = M*V, and R = M*W.
390 Real P[2], Q[2], R[2];
391 for (int row = 0; row < 2; ++row)
392 {
393 P[row] = (Real)0;
394 Q[row] = (Real)0;
395 R[row] = (Real)0;
396 for (int col = 0; col < 2; ++col)
397 {
398 P[row] += mBlend[row][col] * U[col];
399 Q[row] += mBlend[row][col] * V[col];
400 R[row] += mBlend[row][col] * W[col];
401 }
402 }
403
404 // Compute the tensor product (M*U)(M*V)(M*W)*D where D is the 2x2x2
405 // subimage containing (x,y,z).
406 Real result = (Real)0;
407 for (int slice = 0; slice < 2; ++slice)
408 {
409 int zClamp = iz + slice;
410 if (zClamp >= mZBound)
411 {
412 zClamp = mZBound - 1;
413 }
414
415 for (int row = 0; row < 2; ++row)
416 {
417 int yClamp = iy + row;
418 if (yClamp >= mYBound)
419 {
420 yClamp = mYBound - 1;
421 }
422
423 for (int col = 0; col < 2; ++col)
424 {
425 int xClamp = ix + col;
426 if (xClamp >= mXBound)
427 {
428 xClamp = mXBound - 1;
429 }
430
431 result += P[col] * Q[row] * R[slice] *
432 mF[xClamp + mXBound * (yClamp + mYBound * zClamp)];
433 }
434 }
435 }
436 result *= xMult * yMult * zMult;
437
438 return result;
439}
440
441
442}
443
444#endif
445
#define Assert(condition, message)
Definition Exception.hpp:10
Definition TrilinearInterpolation.hpp:25
Real GetXMax() const
Definition TrilinearInterpolation.hpp:143
int GetZBound() const
Definition TrilinearInterpolation.hpp:119
Real GetXMin() const
Definition TrilinearInterpolation.hpp:137
int GetYBound() const
Definition TrilinearInterpolation.hpp:113
Real GetXSpacing() const
Definition TrilinearInterpolation.hpp:149
int GetXBound() const
Definition TrilinearInterpolation.hpp:107
Real GetZMax() const
Definition TrilinearInterpolation.hpp:179
Real GetYMin() const
Definition TrilinearInterpolation.hpp:155
Real GetZMin() const
Definition TrilinearInterpolation.hpp:173
Real operator()(Real x, Real y, Real z) const
Definition TrilinearInterpolation.hpp:191
int GetQuantity() const
Definition TrilinearInterpolation.hpp:125
Real const * GetF() const
Definition TrilinearInterpolation.hpp:131
Real GetZSpacing() const
Definition TrilinearInterpolation.hpp:185
IntpTrilinear3(int xBound, int yBound, int zBound, Real xMin, Real xSpacing, Real yMin, Real ySpacing, Real zMin, Real zSpacing, Real const *F)
Definition TrilinearInterpolation.hpp:70
Real GetYMax() const
Definition TrilinearInterpolation.hpp:161
Real GetYSpacing() const
Definition TrilinearInterpolation.hpp:167
Definition TricubicInterpolation.hpp:25