You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.2 KiB
52 lines
1.2 KiB
9 months ago
|
#pragma once
|
||
|
#include "basedata.h"
|
||
|
#include "comdefs.h"
|
||
|
|
||
|
using michlib::real;
|
||
|
|
||
|
template<class D> class LinearInterpolator: public D
|
||
|
{
|
||
|
public:
|
||
|
LinearInterpolator(D&& d): D(std::move(d)) {}
|
||
|
|
||
|
real operator()(const struct Point2D& in) const
|
||
|
{
|
||
|
const auto gp = D::GridPos(in.x, in.y);
|
||
|
if(!gp.Valid()) return NAN;
|
||
|
|
||
|
if(gp.x == 0.0 && gp.y == 0.0) return D::V(gp.ix, gp.iy);
|
||
|
|
||
|
real v00;
|
||
|
real v10;
|
||
|
real v01;
|
||
|
real v11;
|
||
|
bool isfill = false;
|
||
|
size_t fx, fy;
|
||
|
|
||
|
// Count fills
|
||
|
for(size_t ix = 0; ix <= 1; ix++)
|
||
|
for(size_t iy = 0; iy <= 1; iy++)
|
||
|
{
|
||
|
if(isfill && D::IsFill(gp.ix + ix, gp.iy + iy)) return NAN;
|
||
|
if(D::IsFill(gp.ix + ix, gp.iy + iy))
|
||
|
{
|
||
|
fx = ix;
|
||
|
fy = iy;
|
||
|
isfill = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
v00 = D::V(gp.ix, gp.iy);
|
||
|
v10 = D::V(gp.ix + 1, gp.iy);
|
||
|
v01 = D::V(gp.ix, gp.iy + 1);
|
||
|
v11 = D::V(gp.ix + 1, gp.iy + 1);
|
||
|
|
||
|
if(isfill && fx == 0 && fy == 0) v00 = (v10 + v01 + v11) / 3.0;
|
||
|
if(isfill && fx == 1 && fy == 0) v10 = (v00 + v01 + v11) / 3.0;
|
||
|
if(isfill && fx == 0 && fy == 1) v01 = (v10 + v00 + v11) / 3.0;
|
||
|
if(isfill && fx == 1 && fy == 1) v11 = (v10 + v01 + v00) / 3.0;
|
||
|
|
||
|
return v00 + gp.y * (v01 - v00) + gp.x * ((v10 - v00) + gp.y * (v00 - v01 + v11 - v10));
|
||
|
};
|
||
|
};
|