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.
51 lines
1.2 KiB
51 lines
1.2 KiB
#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)); |
|
}; |
|
};
|
|
|