FACT++  1.0
bool Interpolator2D::CalculateWeights ( )
inlineprivate

Calculate the weights corresponding to the points in the output grid. Weights are calculated by bi-linear interpolation. For interpolation, the triangle which contains the point and has the smallest radius is searched. If this is not available in case of extrapolation, the condition is relaxed and requires only the circle to contain the point. If such circle is not available, the circle with the closest center is chosen.

Definition at line 172 of file Interpolator2D.h.

References Interpolator2D::weight::c, Interpolator2D::weight::w, Interpolator2D::vec::x, and Interpolator2D::vec::y.

Referenced by SetOutputGrid().

173  {
174  weights.reserve(outputGrid.size());
175 
176  // Loop over all points in the output grid
177  for (auto ip=outputGrid.cbegin(); ip<outputGrid.cend(); ip++)
178  {
179  double mindd = DBL_MAX;
180 
181  auto mint = circles.cend();
182  auto minc = circles.cend();
183  auto mind = circles.cend();
184 
185  for (auto ic=circles.cbegin(); ic<circles.cend(); ic++)
186  {
187  // Check if point is inside the triangle
188  if (ic->isInsideTriangle(*ip))
189  {
190  if (mint==circles.cend() || ic->r<mint->r)
191  mint = ic;
192  }
193 
194  // If we have found such a triangle, no need to check for more
195  if (mint!=circles.cend())
196  continue;
197 
198  // maybe at least inside the circle
199  const double dd = ic->dist(*ip);
200  if (dd<ic->r)
201  {
202  if (minc==circles.cend() || ic->r<minc->r)
203  minc = ic;
204  }
205 
206  // If we found such a circle, no need to check for more
207  if (minc!=circles.cend())
208  continue;
209 
210  // then look for the closest circle center
211  if (dd<mindd)
212  {
213  mindd = dd;
214  mind = ic;
215  }
216  }
217 
218  // Choose the best of the three options
219  const auto it = mint==circles.cend() ? (minc==circles.cend() ? mind : minc) : mint;
220  if (it==circles.cend())
221  return false;
222 
223  // Calculate the bi-linear interpolation
224  const vec &p1 = it->p[0];
225  const vec &p2 = it->p[1];
226  const vec &p3 = it->p[2];
227 
228  const double dy23 = p2.y - p3.y;
229  const double dy31 = p3.y - p1.y;
230  const double dy12 = p1.y - p2.y;
231 
232  const double dx32 = p3.x - p2.x;
233  const double dx13 = p1.x - p3.x;
234  const double dx21 = p2.x - p1.x;
235 
236  const double dxy23 = p2^p3;
237  const double dxy31 = p3^p1;
238  const double dxy12 = p1^p2;
239 
240  const double det = dxy12 + dxy23 + dxy31;
241 
242  const double w1 = (dy23*ip->x + dx32*ip->y + dxy23)/det;
243  const double w2 = (dy31*ip->x + dx13*ip->y + dxy31)/det;
244  const double w3 = (dy12*ip->x + dx21*ip->y + dxy12)/det;
245 
246  // Store the original grid-point, the circle's parameters
247  // and the calculate weights
248  weight w;
249  w.x = ip->x;
250  w.y = ip->y;
251  w.c = *it;
252  w.w[0] = w1;
253  w.w[1] = w2;
254  w.w[2] = w3;
255 
256  weights.push_back(w);
257  }
258 
259  return true;
260  }
std::vector< point > outputGrid
positions of the data points (e.g. sensors)
std::vector< circle > circles
positions at which inter-/extrapolated values should be provided
std::vector< weight > weights
the calculated circles/triangles

+ Here is the caller graph for this function: