super sampling
This commit is contained in:
parent
09a285e41c
commit
86fda876b1
|
|
@ -19,7 +19,7 @@ public:
|
|||
* @param longitude Longitude of particle
|
||||
* @return A pair of latitude and longitude of particle.
|
||||
*/
|
||||
virtual std::pair<double, double> advect(int time, double latitude, double longitude) const = 0;
|
||||
virtual std::pair<double, double> advect(int time, double latitude, double longitude, int dt) const = 0;
|
||||
|
||||
// Taken from Parcels https://github.com/OceanParcels/parcels/blob/daa4b062ed8ae0b2be3d87367d6b45599d6f95db/parcels/tools/converters.py#L155
|
||||
const static double metreToDegrees(double metre) {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
EulerAdvectionKernel::EulerAdvectionKernel(std::shared_ptr<UVGrid> grid, int dt) : grid(grid), dt(dt) {}
|
||||
EulerAdvectionKernel::EulerAdvectionKernel(std::shared_ptr<UVGrid> grid) : grid(grid) {}
|
||||
|
||||
std::pair<double, double> EulerAdvectionKernel::advect(int time, double latitude, double longitude) const {
|
||||
std::pair<double, double> EulerAdvectionKernel::advect(int time, double latitude, double longitude, int dt) const {
|
||||
auto [u, v] = bilinearinterpolate(*grid, time, latitude, longitude);
|
||||
|
||||
return {latitude + metreToDegrees(v * dt), longitude + metreToDegrees(u * dt)};
|
||||
|
|
|
|||
|
|
@ -15,10 +15,9 @@
|
|||
class EulerAdvectionKernel: public AdvectionKernel {
|
||||
private:
|
||||
std::shared_ptr<UVGrid> grid;
|
||||
int dt;
|
||||
public:
|
||||
explicit EulerAdvectionKernel(std::shared_ptr<UVGrid> grid, int dt);
|
||||
std::pair<double, double> advect(int time, double latitude, double longitude) const override;
|
||||
explicit EulerAdvectionKernel(std::shared_ptr<UVGrid> grid);
|
||||
std::pair<double, double> advect(int time, double latitude, double longitude, int dt) const override;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
RK4AdvectionKernel::RK4AdvectionKernel(std::shared_ptr<UVGrid> grid, int dt): grid(grid), dt(dt) { }
|
||||
RK4AdvectionKernel::RK4AdvectionKernel(std::shared_ptr<UVGrid> grid): grid(grid) { }
|
||||
|
||||
std::pair<double, double> RK4AdvectionKernel::advect(int time, double latitude, double longitude) const {
|
||||
std::pair<double, double> RK4AdvectionKernel::advect(int time, double latitude, double longitude, int dt) const {
|
||||
auto [u1, v1] = bilinearinterpolate(*grid, time, latitude, longitude);
|
||||
// lon1, lat1 = (particle.lon + u1*.5*particle.dt, particle.lat + v1*.5*particle.dt);
|
||||
double lon1 = longitude + metreToDegrees(u1 * 0.5*dt);
|
||||
|
|
|
|||
|
|
@ -12,10 +12,9 @@
|
|||
class RK4AdvectionKernel: public AdvectionKernel {
|
||||
private:
|
||||
std::shared_ptr<UVGrid> grid;
|
||||
int dt;
|
||||
public:
|
||||
explicit RK4AdvectionKernel(std::shared_ptr<UVGrid> grid, int dt);
|
||||
std::pair<double, double> advect(int time, double latitude, double longitude) const override;
|
||||
explicit RK4AdvectionKernel(std::shared_ptr<UVGrid> grid);
|
||||
std::pair<double, double> advect(int time, double latitude, double longitude, int dt) const override;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,13 @@
|
|||
|
||||
#include "../CartographicTransformation.h"
|
||||
|
||||
|
||||
vtkSmartPointer<SpawnPointCallback> LGlyphLayer::createSpawnPointCallback() {
|
||||
auto newPointCallBack = vtkSmartPointer<SpawnPointCallback>::New();
|
||||
newPointCallBack->setData(data);
|
||||
newPointCallBack->setPoints(points);
|
||||
newPointCallBack->setRen(ren);
|
||||
newPointCallBack->setUVGrid(uvGrid);
|
||||
return newPointCallBack;
|
||||
auto newPointCallBack = vtkSmartPointer<SpawnPointCallback>::New();
|
||||
newPointCallBack->setData(data);
|
||||
newPointCallBack->setPoints(points);
|
||||
newPointCallBack->setRen(ren);
|
||||
newPointCallBack->setUVGrid(uvGrid);
|
||||
return newPointCallBack;
|
||||
}
|
||||
|
||||
// Further notes; current thinking is to allow tracking a particle's age by using a scalar array in the VtkPolyData. This would be incremented for every tick/updateData function call.
|
||||
|
|
@ -33,72 +32,72 @@ vtkSmartPointer<SpawnPointCallback> LGlyphLayer::createSpawnPointCallback() {
|
|||
// TODO: modelling all this in vtkClasses is workable, but ideally i would want to work with a native C++ class. See if this is doable and feasible.
|
||||
|
||||
LGlyphLayer::LGlyphLayer(std::shared_ptr<UVGrid> uvGrid, std::unique_ptr<AdvectionKernel> advectionKernel) {
|
||||
this->ren = vtkSmartPointer<vtkRenderer>::New();
|
||||
this->ren->SetLayer(2);
|
||||
this->ren = vtkSmartPointer<vtkRenderer>::New();
|
||||
this->ren->SetLayer(2);
|
||||
|
||||
this->points = vtkSmartPointer<vtkPoints>::New();
|
||||
this->data = vtkSmartPointer<vtkPolyData>::New();
|
||||
this->data->SetPoints(this->points);
|
||||
this->points = vtkSmartPointer<vtkPoints>::New();
|
||||
this->data = vtkSmartPointer<vtkPolyData>::New();
|
||||
this->data->SetPoints(this->points);
|
||||
|
||||
advector = std::move(advectionKernel);
|
||||
this->uvGrid = uvGrid;
|
||||
advector = std::move(advectionKernel);
|
||||
this->uvGrid = uvGrid;
|
||||
|
||||
auto camera = createNormalisedCamera();
|
||||
ren->SetActiveCamera(camera);
|
||||
auto camera = createNormalisedCamera();
|
||||
ren->SetActiveCamera(camera);
|
||||
|
||||
vtkSmartPointer<vtkTransformFilter> transformFilter = createCartographicTransformFilter(uvGrid);
|
||||
transformFilter->SetInputData(data);
|
||||
vtkSmartPointer<vtkTransformFilter> transformFilter = createCartographicTransformFilter(uvGrid);
|
||||
transformFilter->SetInputData(data);
|
||||
|
||||
vtkNew<vtkGlyphSource2D> circleSource;
|
||||
circleSource->SetGlyphTypeToCircle();
|
||||
circleSource->SetScale(0.05);
|
||||
circleSource->Update();
|
||||
vtkNew<vtkGlyphSource2D> circleSource;
|
||||
circleSource->SetGlyphTypeToCircle();
|
||||
circleSource->SetScale(0.05);
|
||||
circleSource->Update();
|
||||
|
||||
vtkNew<vtkGlyph2D> glyph2D;
|
||||
glyph2D->SetSourceConnection(circleSource->GetOutputPort());
|
||||
glyph2D->SetInputConnection(transformFilter->GetOutputPort());
|
||||
glyph2D->SetColorModeToColorByScalar();
|
||||
glyph2D->Update();
|
||||
vtkNew<vtkGlyph2D> glyph2D;
|
||||
glyph2D->SetSourceConnection(circleSource->GetOutputPort());
|
||||
glyph2D->SetInputConnection(transformFilter->GetOutputPort());
|
||||
glyph2D->SetColorModeToColorByScalar();
|
||||
glyph2D->Update();
|
||||
|
||||
vtkNew<vtkPolyDataMapper> mapper;
|
||||
mapper->SetInputConnection(glyph2D->GetOutputPort());
|
||||
mapper->Update();
|
||||
vtkNew<vtkPolyDataMapper> mapper;
|
||||
mapper->SetInputConnection(glyph2D->GetOutputPort());
|
||||
mapper->Update();
|
||||
|
||||
vtkNew<vtkActor> actor;
|
||||
actor->SetMapper(mapper);
|
||||
vtkNew<vtkActor> actor;
|
||||
actor->SetMapper(mapper);
|
||||
|
||||
this->ren->AddActor(actor);
|
||||
this->ren->AddActor(actor);
|
||||
}
|
||||
|
||||
// creates a few points so we can test the updateData function
|
||||
void LGlyphLayer::spoofPoints() {
|
||||
this->points->InsertNextPoint(-4.125, 61.375 , 0);
|
||||
this->points->InsertNextPoint(6.532949683882039, 53.24308582564463, 0); // Coordinates of Zernike
|
||||
this->points->InsertNextPoint(5.315307819255385, 60.40001057122271, 0); // Coordinates of Bergen
|
||||
this->points->InsertNextPoint( 6.646210231365825, 46.52346296009023, 0); // Coordinates of Lausanne
|
||||
this->points->InsertNextPoint(-6.553894313570932, 62.39522131195857, 0); // Coordinates of the top of the Faroe islands
|
||||
this->points->InsertNextPoint(-4.125, 61.375, 0);
|
||||
this->points->InsertNextPoint(6.532949683882039, 53.24308582564463, 0); // Coordinates of Zernike
|
||||
this->points->InsertNextPoint(5.315307819255385, 60.40001057122271, 0); // Coordinates of Bergen
|
||||
this->points->InsertNextPoint(6.646210231365825, 46.52346296009023, 0); // Coordinates of Lausanne
|
||||
this->points->InsertNextPoint(-6.553894313570932, 62.39522131195857,
|
||||
0); // Coordinates of the top of the Faroe islands
|
||||
|
||||
this->points->Modified();
|
||||
}
|
||||
|
||||
// returns new coords for a point; used to test the updateData function
|
||||
std::pair<double, double> advect(int time, double lat, double lon) {
|
||||
return {lat + 0.01, lon + 0.01};
|
||||
this->points->Modified();
|
||||
}
|
||||
|
||||
void LGlyphLayer::updateData(int t) {
|
||||
double point[3];
|
||||
for (vtkIdType n = 0; n < this->points->GetNumberOfPoints(); n++) {
|
||||
this->points->GetPoint(n, point);
|
||||
auto [yNew, xNew] = advector->advect(t, point[1], point[0]);
|
||||
this->points->SetPoint(n, xNew, yNew, 0);
|
||||
const int SUPERSAMPLINGRATE = 4;
|
||||
double point[3];
|
||||
for (vtkIdType n = 0; n < this->points->GetNumberOfPoints(); n++) {
|
||||
this->points->GetPoint(n, point);
|
||||
for (int i = 0; i < SUPERSAMPLINGRATE; i++) {
|
||||
std::tie(point[1], point[0]) = advector->advect(t, point[1], point[0], (t-lastT)/SUPERSAMPLINGRATE);
|
||||
}
|
||||
this->points->Modified();
|
||||
this->points->SetPoint(n, point[0], point[1], 0);
|
||||
}
|
||||
lastT = t;
|
||||
this->points->Modified();
|
||||
}
|
||||
|
||||
void LGlyphLayer::addObservers(vtkSmartPointer<vtkRenderWindowInteractor> interactor) {
|
||||
auto newPointCallBack = createSpawnPointCallback();
|
||||
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, newPointCallBack);
|
||||
interactor->AddObserver(vtkCommand::LeftButtonReleaseEvent, newPointCallBack);
|
||||
interactor->AddObserver(vtkCommand::MouseMoveEvent, newPointCallBack);
|
||||
auto newPointCallBack = createSpawnPointCallback();
|
||||
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, newPointCallBack);
|
||||
interactor->AddObserver(vtkCommand::LeftButtonReleaseEvent, newPointCallBack);
|
||||
interactor->AddObserver(vtkCommand::MouseMoveEvent, newPointCallBack);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ private:
|
|||
vtkSmartPointer<vtkPolyData> data;
|
||||
std::unique_ptr<AdvectionKernel> advector;
|
||||
std::shared_ptr<UVGrid> uvGrid;
|
||||
int lastT = 1000;
|
||||
|
||||
public:
|
||||
/** Constructor.
|
||||
|
|
|
|||
|
|
@ -22,10 +22,9 @@ using namespace std;
|
|||
|
||||
int main() {
|
||||
shared_ptr<UVGrid> uvGrid = std::make_shared<UVGrid>();
|
||||
auto kernelRK4 = make_unique<RK4AdvectionKernel>(uvGrid, DT);
|
||||
auto kernelRK4 = make_unique<RK4AdvectionKernel>(uvGrid);
|
||||
|
||||
auto l = new LGlyphLayer(uvGrid, move(kernelRK4));
|
||||
// l->spoofPoints();
|
||||
|
||||
Program *program = new Program(DT);
|
||||
program->addLayer(new BackgroundImage("../../../../data/map_661-661.png"));
|
||||
|
|
|
|||
Loading…
Reference in New Issue