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

10 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));
};
};