SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CubicPWI.h
Go to the documentation of this file.
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2009 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 
30 ///
31 ///@class CubicPWI
32 ///@brief Cubic piecewise interpolation
33 ///
34 ///@author
35 /// Alexei Samsonov
36 /// Department of Computer Science
37 /// University of Utah
38 ///
39 ///@date July 2000
40 ///
41 
42 
43 #ifndef SCI_CUBICPWI_H__
44 #define SCI_CUBICPWI_H__
45 
47 
48 #include <Core/Containers/Array1.h>
51 #include <sci_debug.h>
52 
53 #include <iostream>
54 
55 
56 #include <Core/Math/share.h>
57 
58 namespace SCIRun {
59 
61 
62 template <class T> std::ostream&
63 operator<<(std::ostream& out, Array1<T> a)
64 {
65  for (int i = 0; i < a.size(); i++){
66  std::cout << a[i] << std::endl;
67  }
68  return out;
69 }
70 
71 typedef struct Quat {
72  double a;
73  double b;
74  double c;
75  double d;
76 } QUAT;
77 
78 class SCISHARE CubicPWI: public PiecewiseInterp<double> {
79 public:
80  CubicPWI();
81  CubicPWI(const Array1<double>&, const Array1<double>&);
82 
83  bool set_data(const Array1<double>&, const Array1<double>&);
84  inline bool get_value(double, double&);
85 
86 private:
87  Array1<QUAT> p;
88 };
89 
90 inline bool CubicPWI::get_value(double w, double& res)
91 {
92  int i = 0;
93  if (data_valid && (i = get_interval(w)) >= 0) {
94  w -= points[i];
95  res = p[i].a + w * (p[i].b + w * (p[i].c + p[i].d * w));
96  return true;
97  }
98  else
99  return false;
100 }
101 
102 template <class T> class Cubic3DPWI: public PiecewiseInterp<T> {
103 public:
105  Cubic3DPWI(const Array1<double>&, const Array1<T>&);
106 
107  bool set_data(const Array1<double>&, const Array1<T>&);
108  bool set_data(const Array1<double>&, const Array1<T>&,
110  inline bool get_value(double, T&);
111 
112 private:
113  Array1<QUAT> X;
114  Array1<QUAT> Y;
115  Array1<QUAT> Z;
116 };
117 
118 template <class T> Cubic3DPWI<T>::Cubic3DPWI(const Array1<double>& pts,
119  const Array1<T>& vals)
120 {
121  set_data(pts, vals);
122 }
123 
124 template <class T> inline bool Cubic3DPWI<T>::get_value(double w, T& res)
125 {
126  int i;
127  if (this->data_valid && (i = this->get_interval(w)) >= 0) {
128  w -= this->points[i];
129  res = T(X[i].a + w * (X[i].b + w * (X[i].c + X[i].d * w)),
130  Y[i].a + w * (Y[i].b + w * (Y[i].c + Y[i].d * w)),
131  Z[i].a + w * (Z[i].b + w * (Z[i].c + Z[i].d * w)));
132  return true;
133  }
134  else
135  return false;
136 }
137 
138 
141 
142 template <class T> bool
144 {
145  int sz = vals.size();
146  this->reset();
147  Array1<double> drvX, drvY, drvZ;
148  Array1<double> vx, vy, vz;
149  vx.resize(sz);
150  vy.resize(sz);
151  vz.resize(sz);
152 
153  for (int i = 0; i < sz; i++) {
154  vx[i] = vals[i].x();
155  vy[i] = vals[i].y();
156  vz[i] = vals[i].z();
157  }
158 
159  if (set_tangents(pts, vx, drvX, natural_ends) &&
160  set_tangents(pts, vy, drvY, natural_ends)
161  && set_tangents(pts, vz, drvZ, natural_ends)) {
162 #if DEBUG
163  std::cout << "Derivatives are done!!!" << std::endl;
164 #endif
166  drvs.resize(sz);
167  for (int i = 0; i < sz; i++) {
168  drvs[i] = Core::Geometry::Vector(drvX[i], drvY[i], drvZ[i]);
169  }
170  return set_data(pts, vals, drvs);
171  }
172  else {
173  return false;
174  }
175 }
176 
177 // takes sorted array of points
178 template <class T> bool
180  const Array1<Core::Geometry::Vector>& drvs){
181  int sz = 0;
182  this->reset();
183 
184  if (this->fill_data(pts) && (sz = this->points.size()) > 1 &&
185  sz == vals.size() && sz == drvs.size()) {
186 #if DEBUG
187  std::cout << "Inside set_data!!!" << std::endl;
188 #endif
189  X.resize(sz);
190  Y.resize(sz);
191  Z.resize(sz);
192 
193  Array1<double> drvX, drvY, drvZ;
194  Array1<double> vx, vy, vz;
195  vx.resize(sz);
196  vy.resize(sz);
197  vz.resize(sz);
198  drvX.resize(sz);
199  drvY.resize(sz);
200  drvZ.resize(sz);
201 
202  for (int i=0; i < sz; i++) {
203  vx[i] = vals[i].x();
204  vy[i] = vals[i].y();
205  vz[i] = vals[i].z();
206  drvX[i] = drvs[i].x();
207  drvY[i] = drvs[i].y();
208  drvZ[i] = drvs[i].z();
209  }
210 
211  this->data_valid = true;
212  double delta, a, b, c, d;
213 
214  for (int i = 0; i < sz-1; i++)
215  if ( (delta = this->points[i+1] - this->points[i]) > 10e-9) {
216  a = vx[i];
217  b = drvX[i];
218  c = ((3 * (vx[i+1] - vx[i]) / delta) - 2 * drvX[i] - drvX[i+1]) / delta;
219  d = (drvX[i] + drvX[i+1] - (2 * (vx[i+1] - vx[i]) / delta)) / (delta * delta);
220 
221  X[i].a = a;
222  X[i].b = b;
223  X[i].c = c;
224  X[i].d = d;
225 #if DEBUG
226  std::cout << "Interval: " << this->points[i] << ", " << this->points[i+1] << std::endl;
227  std::cout << "Coeff. are for X: " << X[i].a << std::endl << X[i].b
228  << std::endl << X[i].c << std::endl << X[i].d << std::endl;
229 #endif
230  a = vy[i];
231  b = drvY[i];
232  c = (3 * (vy[i+1] - vy[i]) / delta - 2 * drvY[i] - drvY[i+1]) / delta;
233  d = (drvY[i] + drvY[i+1] - 2 * (vy[i+1] - vy[i]) / delta) / (delta * delta);
234 
235  Y[i].a = a;
236  Y[i].b = b;
237  Y[i].c = c;
238  Y[i].d = d;
239 #if DEBUG
240  std::cout << "Interval: " << this->points[i] << ", " << this->points[i+1] << std::endl;
241  std::cout << "Coeff. are for Y: " << Y[i].a << std::endl << Y[i].b
242  << std::endl << Y[i].c << std::endl << Y[i].d << std::endl;
243 #endif
244  a = vz[i];
245  b = drvZ[i];
246  c = (3* (vz[i+1] - vz[i]) / delta- 2 * drvZ[i] - drvZ[i+1]) / delta;
247  d = (drvZ[i] + drvZ[i+1] - 2 * (vz[i+1] - vz[i]) / delta) / (delta * delta);
248 
249  Z[i].a = a;
250  Z[i].b = b;
251  Z[i].c = c;
252  Z[i].d = d;
253  }
254  else {
255 #if DEBUG
256  std::cout << "Delta is small!!! " << std::endl;
257 #endif
258  this->reset();
259  break;
260  }
261  }
262  return this->data_valid;
263 }
264 
265 } // End namespace SCIRun
266 
267 #endif //SCI_CUBICPWI_H__
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 
282 
Definition: CubicPWI.h:60
Interface to dynamic 1D array class.
bool set_data(const Array1< double > &, const Array1< T > &)
Definition: CubicPWI.h:143
double c
Definition: CubicPWI.h:74
Definition: PiecewiseInterp.h:60
bool get_value(double, double &)
Definition: CubicPWI.h:90
#define SCISHARE
Definition: share.h:39
Definition: CubicPWI.h:60
EndCondition
Definition: CubicPWI.h:60
Definition: CubicPWI.h:71
Definition: Vector.h:63
struct SCIRun::Quat QUAT
bool set_tangents(const Array1< double > &pts, const Array1< double > &vals, Array1< double > &r, EndCondition end_conds)
Definition: CubicPWI.cc:60
Definition: CubicPWI.h:60
double b
Definition: CubicPWI.h:73
double d
Definition: CubicPWI.h:75
Definition: CubicPWI.h:102
double a
Definition: CubicPWI.h:72
Array1< double > points
Definition: PiecewiseInterp.h:66
bool get_value(double, T &)
Definition: CubicPWI.h:124
Definition: CubicPWI.h:60
Cubic3DPWI()
Definition: CubicPWI.h:104
Definition: CubicPWI.h:78
bool data_valid
Definition: PiecewiseInterp.h:62