40 ndarray::Array<double, 1, 1> BoundedField::evaluate(ndarray::Array<double const, 1>
const &
x,
41 ndarray::Array<double const, 1>
const &
y)
const {
42 ndarray::Array<double, 1, 1> out = ndarray::allocate(
x.getSize<0>());
43 for (
int i = 0, n =
x.getSize<0>(); i < n; ++i) {
44 out[i] = evaluate(
x[i],
y[i]);
62 template <
typename T,
typename U>
63 void operator()(T &out, U
a)
const {
69 explicit ScaledAdd(
double s) :
scaleBy(s) {}
71 template <
typename T,
typename U>
72 void operator()(T &out, U
a)
const {
80 template <
typename T,
typename U>
81 void operator()(T &out, U
a)
const {
87 template <
typename T,
typename U>
88 void operator()(T &out, U
a)
const {
110 explicit Bounds(
int step_) :
step(step_),
min(0),
max(0),
end(0) {}
113 void reset(
int min_) {
126 _z00(
std::numeric_limits<double>::quiet_NaN()),
127 _z01(
std::numeric_limits<double>::quiet_NaN()),
128 _z10(
std::numeric_limits<double>::quiet_NaN()),
129 _z11(
std::numeric_limits<double>::quiet_NaN()) {}
135 template <
typename T,
typename F>
138 while (_y.end < _region->
getEndY()) {
139 _runRow(img, functor);
147 _runRow(img, functor);
153 template <
typename T,
typename F>
156 _z00 = _field->evaluate(_x.min, _y.min);
157 _z01 = _field->evaluate(_x.min, _y.max);
158 while (_x.max < _region->
getEndX()) {
159 _z10 = _field->evaluate(_x.max, _y.min);
160 _z11 = _field->evaluate(_x.max, _y.max);
161 _runCell(img, functor);
171 _z10 = _field->evaluate(_x.max, _y.min);
172 _z11 = _field->evaluate(_x.max, _y.max);
173 _runCell(img, functor);
181 template <
typename T,
typename F>
183 int dy = _y.max - _y.min;
184 int dx = _x.max - _x.min;
191 auto rowIter = img.
x_at(_x.min - img.
getX0(), _y.min - img.
getY0());
193 functor(*rowIter, _z00);
196 for (
int x = _x.min + 1;
x < _x.end; ++
x, ++rowIter) {
197 functor(*rowIter, ((_x.max -
x) * _z00 + (
x - _x.min) * _z10) / dx);
200 for (
int y = _y.min + 1;
y < _y.end; ++
y) {
202 double z0 = ((_y.max -
y) * _z00 + (
y - _y.min) * _z01) / dy;
203 double z1 = ((_y.max -
y) * _z10 + (
y - _y.min) * _z11) / dy;
205 functor(*rowIter, z0);
208 for (
int x = _x.min + 1;
x < _x.end; ++
x, ++rowIter) {
209 functor(*rowIter, ((_x.max -
x) * z0 + (
x - _x.min) * z1) / dx);
214 BoundedField
const *_field;
218 double _z00, _z01, _z10, _z11;
221 template <
typename T,
typename F>
222 void applyToImage(BoundedField
const &
field,
image::Image<T> &img, F functor,
bool overlapOnly,
int xStep,
229 "Image bounding box does not match field bounding box");
232 if (yStep > 1 || xStep > 1) {
233 Interpolator interpolator(&
field, ®ion, xStep, yStep);
234 interpolator.run(img, functor);
238 auto subImage = img.
subset(region);
239 auto size = region.getWidth();
240 ndarray::Array<double, 1> xx = ndarray::allocate(ndarray::makeVector(size));
241 ndarray::Array<double, 1> yy = ndarray::allocate(ndarray::makeVector(size));
243 std::iota(xx.begin(), xx.end(), region.getBeginX());
244 auto outRowIter = subImage.getArray().begin();
245 for (
int y = region.getBeginY();
y < region.getEndY(); ++
y, ++outRowIter) {
247 functor(*outRowIter,
field.evaluate(xx, yy));
258 template <
typename T>
259 void BoundedField::fillImage(
image::Image<T> &img,
bool overlapOnly,
int xStep,
int yStep)
const {
260 applyToImage(*
this, img, Assign(), overlapOnly, xStep, yStep);
263 template <
typename T>
266 applyToImage(*
this, img, ScaledAdd(
scaleBy), overlapOnly, xStep, yStep);
269 template <
typename T>
270 void BoundedField::multiplyImage(
image::Image<T> &img,
bool overlapOnly,
int xStep,
int yStep)
const {
271 applyToImage(*
this, img, Multiply(), overlapOnly, xStep, yStep);
274 template <
typename T>
275 void BoundedField::divideImage(
image::Image<T> &img,
bool overlapOnly,
int xStep,
int yStep)
const {
276 applyToImage(*
this, img, Divide(), overlapOnly, xStep, yStep);
279 #define INSTANTIATE(T) \
280 template void BoundedField::fillImage(image::Image<T> &, bool, int, int) const; \
281 template void BoundedField::addToImage(image::Image<T> &, double, bool, int, int) const; \
282 template void BoundedField::multiplyImage(image::Image<T> &, bool, int, int) const; \
283 template void BoundedField::divideImage(image::Image<T> &, bool, int, int) const