#ifndef RASTER_H
#define RASTER_H
#include <cassert>
#include "track.h"
class TouchPoint;
typedef std::vector<TouchPoint> TouchPointList;
class Painter {
public:
virtual ~Painter() { }
virtual Real get_min_height() const = 0;
virtual Vector2 get_radius_xy() const = 0;
virtual Real get_height_xy(const Vector2 &offset) const = 0;
};
class Raster {
private:
Real *data;
int width;
int height;
public:
explicit Raster(int width = 0, int height = 0, Real value = 0):
data(), width(), height()
{ resize(width, height, value); }
~Raster() { reset(); }
void fill(Real value) {
if (data)
for(Real *i = data, *e = i + width*height; i < e; ++i)
*i = value;
}
void resize(int width, int height, Real value = 0) {
if (data) delete[] data;
data = 0;
this->width = this->height = 0;
if (width > 0 && height > 0) {
this->width = width;
this->height = height;
this->data = new Real[width*height];
fill(value);
}
}
void reset() { resize(0, 0); }
int get_width() const { return width; }
int get_height() const { return height; }
const Real* get_data() const { return data; }
const Real* operator[](int row) const
{ assert(data); return data + row*width; }
Real* get_data() { return data; }
Real* operator[](int row)
{ assert(data); return data + row*width; }
Real get(int x, int y, Real def = 0) const
{ return x >= 0 && y >= 0 && x < width && y < height ? (*this)[y][x] : def; }
void set(int x, int y, Real value)
{ if (x >= 0 && y >= 0 && x < width && y < height) (*this)[y][x] = value; }
void touch(const Painter &painter, const Vector2 &position, int index, TouchPointList &points);
};
class TouchPoint {
public:
int index;
int row;
int col;
Real prev;
Real next;
TouchPoint(int index = 0, int row = 0, int col = 0, Real prev = 0, Real next = 0):
index(index), row(row), col(col), prev(prev), next(next) { }
void apply_next(Raster &raster) const
{ raster.set(col, row, next); }
void apply_prev(Raster &raster) const
{ raster.set(col, row, prev); }
};
class FlatRaster {
public:
Real x0;
Real x1;
Real y0;
Real y1;
Real min_value;
Real max_value;
Raster raster;
explicit FlatRaster(
int xpixels = 0,
int ypixels = 0,
Real x0 = 0,
Real x1 = 1,
Real y0 = 0,
Real y1 = 1,
Real min_value = 0,
Real max_value = 1
):
x0(x0),
x1(x1),
y0(y0),
y1(y1),
min_value(min_value),
max_value(max_value),
raster(xpixels, ypixels, min_value)
{ }
Vector4 color_by_distance(Real d) const;
void draw() const;
};
class PolarRaster {
public:
Real x0;
Real x1;
Real min_value;
Real max_value;
Raster raster;
explicit PolarRaster(
int xpixels = 0,
int ypixels = 0,
Real x0 = 0,
Real x1 = 1,
Real min_value = 0,
Real max_value = 1
):
x0(x0),
x1(x1),
min_value(min_value),
max_value(max_value),
raster(xpixels, ypixels, min_value)
{ }
Vector4 color_by_distance(Real d) const;
void draw() const;
};
#endif