xmsinterp  1.0
InterpCt.cpp
Go to the documentation of this file.
1 //------------------------------------------------------------------------------
6 //------------------------------------------------------------------------------
7 
8 //----- Included files ---------------------------------------------------------
9 
10 // 1. Precompiled header
11 
12 // 2. My header
14 
15 // 3. Standard Library Headers
16 #include <sstream>
17 
18 // 4. External Library Headers
19 
20 // 5. Shared Headers
22 #include <xmscore/points/pt.h>
23 #include <xmscore/stl/utility.h>
25 
26 // 6. Non-shared Headers
27 
28 //----- Forward declarations ---------------------------------------------------
29 
30 //----- External globals -------------------------------------------------------
31 
32 //----- Namespace declaration --------------------------------------------------
33 namespace xms
34 {
36 #define SQRT3 1.73205080756888772935274463415059
37 
38 //----- Constants / Enumerations -----------------------------------------------
39 
40 //----- Classes / Structs ------------------------------------------------------
41 
42 //----- Internal functions -----------------------------------------------------
43 
44 //----- Class / Function definitions -------------------------------------------
45 
50 //------------------------------------------------------------------------------
54 //------------------------------------------------------------------------------
55 InterpCt::InterpCt(const std::vector<Pt3d>& a_pts, BSHP<NodalFunc> a_n)
56 : m_pts(a_pts)
57 , m_nodalFunc(a_n)
58 {
59 } // InterpCt::InterpCt
60 //------------------------------------------------------------------------------
65 //------------------------------------------------------------------------------
67 {
68  if (e > 0)
69  {
70  if (n > (-SQRT3 / 3 * e))
71  return T2;
72  else
73  return T1;
74  }
75  else if (n > (SQRT3 / 3 * e))
76  return T3;
77  return T1;
78 } // InterpCt::DetermineRegion
79 //------------------------------------------------------------------------------
81 //------------------------------------------------------------------------------
83 {
84  if (m_nodalFunc)
85  m_nodalFunc->ComputeNodalFuncs();
86 } // InterpCt::RecalcNodalFunc
87 //------------------------------------------------------------------------------
90 //------------------------------------------------------------------------------
91 std::string InterpCt::ToString() const
92 {
93  std::stringstream ss;
94  VecToStream(ss, m_pts, "pts");
95  ss << x1 << "=x1 " << p1 << "=p1 " << f1 << "=f1 " << x2 << "=x2 " << y2 << "=y2 " << f2 << "=f2 "
96  << x3 << "=x3 " << y3 << "=y3 " << f3 << "=f3 " << d11 << "=d11 " << d12 << "=d12 " << d21
97  << "=d21 " << d22 << "=d22 " << fx1 << "=fx1 " << fy1 << "=fy1 " << fx2 << "=fx2 " << fy2
98  << "=fy2 " << fx3 << "=fx3 " << fy3 << "=fy3 "
99 
100  << ue1 << "=ue1 " << un1 << "=un1 " << ue2 << "=ue2 " << un2 << "=un2 " << ue3 << "=ue3 "
101  << un3 << "=un3 " << ue4 << "=ue4 " << un4 << "=un4 " << ue5 << "=ue5 " << un5 << "=un5 "
102  << ue6 << "=ue6 " << un6 << "=un6 "
103 
104  << dudz1 << "=dudz1 " << dudz2 << "=dudz2 " << dudz3 << "=dudz3 " << dudw1 << "=dudw1 "
105  << dudw2 << "=dudw2 " << dudw3 << "=dudw3 " << dudn4 << "=dudn4 " << dudn5 << "=dudn5 "
106  << dudn6 << "=dudn6 "
107 
108  << delta << "=delta " << a11 << "=a11 " << a12 << "=a12 " << a21 << "=a21 " << a22 << "=a22 "
109  << d1 << "=d1 " << d2 << "=d2 "
110  << "\n";
111  return ss.str();
112 } // InterpCt::ToString
113 //------------------------------------------------------------------------------
117 //------------------------------------------------------------------------------
118 double InterpCt::InterpToPt(const Pt3d& a_pt)
119 {
120  double e, n, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12;
121 
122  e = a11 * a_pt.x + a12 * a_pt.y + d1;
123  n = a21 * a_pt.x + a22 * a_pt.y + d2;
124  RegionEnum region = DetermineRegion(e, n);
125 
126  // compute cardinal functions
127  b1 = (1.0 / 3.0) + (SQRT3 / 2.0) * n;
128  b2 = (1.0 / 3.0) - 0.75 * e - (SQRT3 / 4.0) * n;
129  b3 = (1.0 / 3.0) + 0.75 * e - (SQRT3 / 4.0) * n;
130  b4 = 0.25 * e + (SQRT3 / 2.0) * e * n;
131  b5 = -0.125 * e + (SQRT3 / 8.0) * n + 0.375 * e * e - (SQRT3 / 4.0) * e * n - 0.375 * n * n;
132  b6 = -0.125 * e - (SQRT3 / 8.0) * n - 0.375 * e * e - (SQRT3 / 4.0) * e * n + 0.375 * n * n;
133  b7 = -(7.0 * SQRT3 / 81.0) - (13.0 / 36.0) * n + (SQRT3 / 18.0) * n * n;
134  b8 = -(7.0 * SQRT3 / 81.0) + (13.0 * SQRT3 / 72.0) * e + (13.0 / 72.0) * n +
135  (SQRT3 / 24.0) * e * e + (1.0 / 12.0) * e * n + (SQRT3 / 72.0) * n * n;
136  b9 = -(7.0 * SQRT3 / 81.0) - (13.0 * SQRT3 / 72.0) * e + (13.0 / 72.0) * n +
137  (SQRT3 / 24.0) * e * e - (1.0 / 12.0) * e * n + (SQRT3 / 72.0) * n * n;
138  b10 = -(4.0 * SQRT3 / 81.0) - (SQRT3 / 9.0) * e - (1.0 / 9.0) * n - 0.66666667 * e * n +
139  (2.0 * SQRT3 / 9.0) * n * n;
140  b11 = -(4.0 * SQRT3 / 81.0) + (SQRT3 / 9.0) * e - (1.0 / 9.0) * n + 0.66666667 * e * n +
141  (2.0 * SQRT3 / 9.0) * n * n;
142  b12 = -(4.0 * SQRT3 / 81.0) + (2.0 / 9.0) * n + (SQRT3 / 3.0) * e * e - (SQRT3 / 9.0) * n * n;
143  switch (region)
144  {
145  case T1:
146  b1 = b1 - (SQRT3 / 2.0) * n * n * n;
147  b2 = b2 + 0.25 * e * e * e + (SQRT3 / 4.0) * n * n * n;
148  b3 = b3 - 0.25 * e * e * e + (SQRT3 / 4.0) * n * n * n;
149  b4 = b4 + 0.75 * e * n * n;
150  b5 = b5 - 0.125 * e * e * e + (SQRT3 / 4.0) * e * e * n - (3.0 * SQRT3 / 8.0) * n * n * n;
151  b6 = b6 - 0.125 * e * e * e - (SQRT3 / 4.0) * e * e * n + (3.0 * SQRT3 / 8.0) * n * n * n;
152  b7 = b7 + (17.0 / 36.0) * n * n * n;
153  b8 = b8 - (SQRT3 / 8.0) * e * e * e - 0.25 * e * e * n - (SQRT3 / 12.0) * e * n * n -
154  (11.0 / 72.0) * n * n * n;
155  b9 = b9 + (SQRT3 / 8.0) * e * e * e - 0.25 * e * e * n + (SQRT3 / 12.0) * e * n * n -
156  (11.0 / 72.0) * n * n * n;
157  b10 = b10 + (5.0 / 9.0) * n * n * n - (SQRT3 / 3.0) * e * n * n;
158  b11 = b11 + (5.0 / 9.0) * n * n * n + (SQRT3 / 3.0) * e * n * n;
159  b12 = b12 + e * e * n - (13.0 / 9.0) * n * n * n;
160  break;
161  case T2:
162  b1 = b1 - 0.25 * e * e * e - (3.0 * SQRT3 / 8.0) * e * e * n - (SQRT3 / 8.0) * n * n * n;
163  b2 = b2 + (9.0 / 16.0) * e * e * e + (9.0 * SQRT3 / 16.0) * e * e * n +
164  (9.0 / 16.0) * e * n * n + (SQRT3 / 16.0) * n * n * n;
165  b3 = b3 - (5.0 / 16.0) * e * e * e - (3.0 * SQRT3 / 16.0) * e * e * n -
166  (9.0 / 16.0) * e * n * n + (SQRT3 / 16.0) * n * n * n;
167  b4 = b4 - (5.0 / 16.0) * e * e * e - (5.0 * SQRT3 / 8.0) * e * e * n - (3.0 / 16.0) * e * n * n;
168  b5 = b5 - (9.0 / 32.0) * e * e * e + (3.0 * SQRT3 / 32.0) * e * e * n +
169  (15.0 / 32.0) * e * n * n + (3.0 * SQRT3 / 32.0) * n * n * n;
170  b6 = b6 + (11.0 / 32.0) * e * e * e + (17.0 * SQRT3 / 32.0) * e * e * n +
171  (15.0 / 32.0) * e * n * n - (3.0 * SQRT3 / 32.0) * n * n * n;
172  b7 = b7 + (41.0 / 144.0) * n * n * n + (1.0 / (8.0 * SQRT3)) * e * e * e +
173  (3.0 / 16.0) * e * e * n;
174  b8 = b8 - (17.0 * SQRT3 / 96.0) * e * e * e - (17.0 / 32.0) * e * e * n -
175  (17.0 * SQRT3 / 96.0) * e * n * n - (17.0 / 288.0) * n * n * n;
176  b9 = b9 + (13.0 * SQRT3 / 96.0) * e * e * e - (5.0 / 32.0) * e * e * n +
177  (17.0 * SQRT3 / 96.0) * e * n * n - (17.0 / 288.0) * n * n * n;
178  b10 = b10 - (7.0 / 36.0) * n * n * n + (5.0 * SQRT3 / 12.0) * e * e * e + 2.25 * e * e * n +
179  (5.0 * SQRT3 / 12.0) * e * n * n;
180  b11 = b11 - (7.0 / 36.0) * n * n * n - (SQRT3 / 12.0) * e * e * e - 0.75 * e * e * n -
181  (5.0 * SQRT3 / 12.0) * e * n * n;
182  b12 = b12 - (SQRT3 / 3.0) * e * e * e - 0.5 * e * e * n + (1.0 / 18.0) * n * n * n;
183  break;
184  case T3:
185  b1 = b1 + 0.25 * e * e * e - (3.0 * SQRT3 / 8.0) * e * e * n - (SQRT3 / 8.0) * n * n * n;
186  b2 = b2 + (5.0 / 16.0) * e * e * e - (3.0 * SQRT3 / 16.0) * e * e * n +
187  (9.0 / 16.0) * e * n * n + (SQRT3 / 16.0) * n * n * n;
188  b3 = b3 - (9.0 / 16.0) * e * e * e + (9.0 * SQRT3 / 16.0) * e * e * n -
189  (9.0 / 16.0) * e * n * n + (SQRT3 / 16.0) * n * n * n;
190  b4 = b4 - (5.0 / 16.0) * e * e * e + (5.0 * SQRT3 / 8.0) * e * e * n - (3.0 / 16.0) * e * n * n;
191  b5 = b5 + (11.0 / 32.0) * e * e * e - (17.0 * SQRT3 / 32.0) * e * e * n +
192  (15.0 / 32.0) * e * n * n + (3.0 * SQRT3 / 32.0) * n * n * n;
193  b6 = b6 - (9.0 / 32.0) * e * e * e - (3.0 * SQRT3 / 32.0) * e * e * n +
194  (15.0 / 32.0) * e * n * n - (3.0 * SQRT3 / 32.0) * n * n * n;
195  b7 = b7 + (41.0 / 144.0) * n * n * n - (1.0 / (8.0 * SQRT3)) * e * e * e +
196  (3.0 / 16.0) * e * e * n;
197  b8 = b8 - (13.0 * SQRT3 / 96.0) * e * e * e - (5.0 / 32.0) * e * e * n -
198  (17.0 * SQRT3 / 96.0) * e * n * n - (17.0 / 288.0) * n * n * n;
199  b9 = b9 + (17.0 * SQRT3 / 96.0) * e * e * e - (17.0 / 32.0) * e * e * n +
200  (17.0 * SQRT3 / 96.0) * e * n * n - (17.0 / 288.0) * n * n * n;
201  b10 = b10 - (7.0 / 36.0) * n * n * n + (SQRT3 / 12.0) * e * e * e - 0.75 * e * e * n +
202  (5.0 * SQRT3 / 12.0) * e * n * n;
203  b11 = b11 - (7.0 / 36.0) * n * n * n - (5.0 * SQRT3 / 12.0) * e * e * e + 2.25 * e * e * n -
204  (5.0 * SQRT3 / 12.0) * e * n * n;
205  b12 = b12 + (SQRT3 / 3.0) * e * e * e - 0.5 * e * e * n + (1.0 / 18.0) * n * n * n;
206  break;
207  }
208 
209  return (b1 * f1 + b2 * f2 + b3 * f3 + b4 * dudz1 + b5 * dudz2 + b6 * dudz3 + b7 * dudw1 +
210  b8 * dudw2 + b9 * dudw3 + b10 * dudn4 + b11 * dudn5 + b12 * dudn6);
211 } // CloughTocher::InterpToPt
212 //------------------------------------------------------------------------------
216 //------------------------------------------------------------------------------
217 bool InterpCt::ComputeCtCoeff(int* a_ptIdxs)
218 {
219  int ptIdx[3];
220  for (int i = 0; i < 3; ++i)
221  ptIdx[i] = a_ptIdxs[i];
222  if (ptIdx[0] < 0 || ptIdx[1] < 0 || ptIdx[2] < 0)
223  return false;
224  x1 = m_pts[ptIdx[0]].x;
225  p1 = m_pts[ptIdx[0]].y;
226  f1 = m_pts[ptIdx[0]].z;
227 
228  x2 = m_pts[ptIdx[2]].x;
229  y2 = m_pts[ptIdx[2]].y;
230  f2 = m_pts[ptIdx[2]].z;
231 
232  x3 = m_pts[ptIdx[1]].x;
233  y3 = m_pts[ptIdx[1]].y;
234  f3 = m_pts[ptIdx[1]].z;
235 
236  delta = x3 * p1 - x1 * y3 + x1 * y2 - x2 * p1 + x2 * y3 - x3 * y2;
237  a11 = (2.0 * p1 - y3 - y2) / delta;
238  a12 = (-2.0 * x1 + x2 + x3) / delta;
239  d1 = (x1 * (y3 + y2) - p1 * (x3 + x2)) / delta;
240  a21 = (-SQRT3 * (y3 - y2)) / delta;
241  a22 = (SQRT3 * (x3 - x2)) / delta;
242  d2 = 2 / SQRT3 + (SQRT3 * (x1 * (y3 - y2) - p1 * (x3 - x2))) / delta;
243 
244  d11 = 0.5 * (x3 - x2);
245  d12 = (1.0 / (2.0 * SQRT3)) * (2.0 * x1 - x2 - x3);
246  d21 = 0.5 * (y3 - y2);
247  d22 = (1.0 / (2.0 * SQRT3)) * (2.0 * p1 - y2 - y3);
248 
249  fx1 = fy1 = fx2 = fy2 = fx3 = fy3 = 0;
250  if (m_nodalFunc)
251  {
252  Pt3d grad;
253  m_nodalFunc->GradientFromPtIdx(ptIdx[0], grad);
254  fx1 = grad.x;
255  fy1 = grad.y;
256  m_nodalFunc->GradientFromPtIdx(ptIdx[2], grad);
257  fx2 = grad.x;
258  fy2 = grad.y;
259  m_nodalFunc->GradientFromPtIdx(ptIdx[1], grad);
260  fx3 = grad.x;
261  fy3 = grad.y;
262  }
263 
264  ue1 = d11 * fx1 + d21 * fy1;
265  un1 = d12 * fx1 + d22 * fy1;
266  ue2 = d11 * fx2 + d21 * fy2;
267  un2 = d12 * fx2 + d22 * fy2;
268  ue3 = d11 * fx3 + d21 * fy3;
269  un3 = d12 * fx3 + d22 * fy3;
270  ue4 = 0.5 * (ue1 + ue3);
271  un4 = 0.5 * (un1 + un3);
272  ue5 = 0.5 * (ue1 + ue2);
273  un5 = 0.5 * (un1 + un2);
274  ue6 = 0.5 * (ue2 + ue3);
275  un6 = 0.5 * (un2 + un3);
276 
277  dudz1 = ue1;
278  dudz2 = -0.5 * ue2 + (SQRT3 / 2) * un2;
279  dudz3 = -0.5 * ue3 - (SQRT3 / 2) * un3;
280  dudw1 = un1;
281  dudw2 = -(SQRT3 / 2) * ue2 - 0.5 * un2;
282  dudw3 = (SQRT3 / 2) * ue3 - 0.5 * un3;
283  dudn4 = (SQRT3 / 2) * ue4 + 0.5 * un4;
284  dudn5 = -(SQRT3 / 2) * ue5 + 0.5 * un5;
285  dudn6 = -un6;
286  return true;
287 } // CloughTocher::ComputeCtCoeff
288 
289 } // namespace xms
RegionEnum
Triangle region enumeration.
Definition: InterpCt.h:29
const std::vector< Pt3d > & m_pts
input points interpolated from
Definition: InterpCt.h:40
BSHP< NodalFunc > m_nodalFunc
nodal function used in ct calculations
Definition: InterpCt.h:42
double InterpToPt(const Pt3d &a_pt)
Performs Clough Tocher interpolation to a point.
Definition: InterpCt.cpp:118
void VecToStream(std::stringstream &a_ss, const T &a_v, std::string a_label)
RegionEnum DetermineRegion(double e, double n)
Finds the region of the triangle.
Definition: InterpCt.cpp:66
InterpCt(const std::vector< Pt3d > &a_pts, BSHP< NodalFunc > a_n)
Constructor.
Definition: InterpCt.cpp:55
#define SQRT3
square root of 3 precalculated
Definition: InterpCt.cpp:36
std::string ToString() const
serialize the class to a string.
Definition: InterpCt.cpp:91
void RecalcNodalFunc()
Recalculated the nodal function. This happens when the scalars change.
Definition: InterpCt.cpp:82
bool ComputeCtCoeff(int *a_ptIdxs)
Calculates the coefficients used by ct interpolation.
Definition: InterpCt.cpp:217