diff --git a/vtk/src/CartographicTransformation.cpp b/vtk/src/CartographicTransformation.cpp index 54c528e..5518d61 100644 --- a/vtk/src/CartographicTransformation.cpp +++ b/vtk/src/CartographicTransformation.cpp @@ -15,11 +15,11 @@ vtkSmartPointer createNormalisedCamera() { return camera; } -vtkSmartPointer getCartographicTransformMatrix() { - const double XMin = -15.875; - const double XMax = 12.875; - const double YMin = 46.125; - const double YMax = 62.625; +vtkSmartPointer getCartographicTransformMatrix(const std::shared_ptr uvGrid) { + const double XMin = uvGrid->lons.front(); + const double XMax = uvGrid->lons.back(); + const double YMin = uvGrid->lats.front(); + const double YMax = uvGrid->lats.back(); double eyeTransform[] = { 2/(XMax-XMin), 0, 0, -(XMax+XMin)/(XMax-XMin), @@ -34,10 +34,10 @@ vtkSmartPointer getCartographicTransformMatrix() { } // Assumes Normalised camera is used -vtkSmartPointer createCartographicTransformFilter() { +vtkSmartPointer createCartographicTransformFilter(const std::shared_ptr uvGrid) { vtkNew transform; - transform->SetMatrix(getCartographicTransformMatrix()); + transform->SetMatrix(getCartographicTransformMatrix(uvGrid)); vtkSmartPointer transformFilter = vtkSmartPointer::New(); transformFilter->SetTransform(transform); diff --git a/vtk/src/CartographicTransformation.h b/vtk/src/CartographicTransformation.h index 56ffbeb..e615a26 100644 --- a/vtk/src/CartographicTransformation.h +++ b/vtk/src/CartographicTransformation.h @@ -1,5 +1,6 @@ #include #include +#include "advection/UVGrid.h" #ifndef VTKBASE_NORMALISEDCARTOGRAPHICCAMERA_H #define VTKBASE_NORMALISEDCARTOGRAPHICCAMERA_H @@ -16,15 +17,14 @@ vtkSmartPointer createNormalisedCamera(); /** * Constructs a 4x4 projection matrix that maps homogenious (longitude, latitude, 0, 1) points * to the normalised space. - * TODO: This will soon require UVGrid as a parameter after the advection code is merged properly. * TODO: This transformation has room for improvement see: * https://github.com/MakeNEnjoy/interactive-track-and-trace/issues/12 * @return pointer to 4x4 matrix */ -vtkSmartPointer getCartographicTransformMatrix(); +vtkSmartPointer getCartographicTransformMatrix(const std::shared_ptr uvGrid); /** * Convenience function that converts the 4x4 projection matrix into a vtkTransformFilter * @return pointer to transform filter */ -vtkSmartPointer createCartographicTransformFilter(); \ No newline at end of file +vtkSmartPointer createCartographicTransformFilter(const std::shared_ptr uvGrid); \ No newline at end of file diff --git a/vtk/src/Program.cpp b/vtk/src/Program.cpp index bcb3e61..5f1cf3c 100644 --- a/vtk/src/Program.cpp +++ b/vtk/src/Program.cpp @@ -33,21 +33,22 @@ void Program::setWinProperties() { interact->SetInteractorStyle(style); } -void Program::setupTimer() { +void Program::setupTimer(int dt) { auto callback = vtkSmartPointer::New(this); callback->SetClientData(this); + callback->setDt(dt); this->interact->AddObserver(vtkCommand::TimerEvent, callback); this->interact->AddObserver(vtkCommand::KeyPressEvent, callback); this->interact->CreateRepeatingTimer(17); // 60 fps == 1000 / 60 == 16.7 ms per frame } -Program::Program() { +Program::Program(int timerDT) { this->win = vtkSmartPointer::New(); this->interact = vtkSmartPointer::New(); this->win->SetNumberOfLayers(0); setWinProperties(); - setupTimer(); + setupTimer(timerDT); } diff --git a/vtk/src/Program.h b/vtk/src/Program.h index 4097e4c..fbe5023 100644 --- a/vtk/src/Program.h +++ b/vtk/src/Program.h @@ -31,14 +31,14 @@ private: /** This function sets up and connects a TimerCallbackCommand with the program. */ - void setupTimer(); + void setupTimer(int dt); void setupInteractions(); public: /** Constructor. */ - Program(); + Program(int timerDT); /** This function adds a new layer (and thus vtkRenderer) to the program. * The layer is expected to set its own position in the vtkRenderWindow layer system. diff --git a/vtk/src/advection/AdvectionKernel.h b/vtk/src/advection/AdvectionKernel.h index d8d7674..50da1ce 100644 --- a/vtk/src/advection/AdvectionKernel.h +++ b/vtk/src/advection/AdvectionKernel.h @@ -11,7 +11,6 @@ */ class AdvectionKernel { public: - const static int DT = 15 * 60 * 15; // 60 sec/min * 15 mins /** * This function must take a time, latitude and longitude of a particle and must output * a new latitude and longitude after being advected once for AdvectionKernel::DT time as defined above. diff --git a/vtk/src/advection/EulerAdvectionKernel.cpp b/vtk/src/advection/EulerAdvectionKernel.cpp index 1a38944..82059cc 100644 --- a/vtk/src/advection/EulerAdvectionKernel.cpp +++ b/vtk/src/advection/EulerAdvectionKernel.cpp @@ -4,10 +4,10 @@ using namespace std; -EulerAdvectionKernel::EulerAdvectionKernel(std::shared_ptr grid): grid(grid) { } +EulerAdvectionKernel::EulerAdvectionKernel(std::shared_ptr grid, int dt) : grid(grid), dt(dt) {} std::pair EulerAdvectionKernel::advect(int time, double latitude, double longitude) const { - auto [u, v] = bilinearinterpolate(*grid, time, latitude, longitude); + auto [u, v] = bilinearinterpolate(*grid, time, latitude, longitude); - return {latitude+metreToDegrees(v*DT), longitude+metreToDegrees(u*DT)}; + return {latitude + metreToDegrees(v * dt), longitude + metreToDegrees(u * dt)}; } diff --git a/vtk/src/advection/EulerAdvectionKernel.h b/vtk/src/advection/EulerAdvectionKernel.h index d9893cb..e2d9353 100644 --- a/vtk/src/advection/EulerAdvectionKernel.h +++ b/vtk/src/advection/EulerAdvectionKernel.h @@ -15,8 +15,9 @@ class EulerAdvectionKernel: public AdvectionKernel { private: std::shared_ptr grid; + int dt; public: - explicit EulerAdvectionKernel(std::shared_ptr grid); + explicit EulerAdvectionKernel(std::shared_ptr grid, int dt); std::pair advect(int time, double latitude, double longitude) const override; }; diff --git a/vtk/src/advection/RK4AdvectionKernel.cpp b/vtk/src/advection/RK4AdvectionKernel.cpp index 1edc9f9..2e62fdf 100644 --- a/vtk/src/advection/RK4AdvectionKernel.cpp +++ b/vtk/src/advection/RK4AdvectionKernel.cpp @@ -3,33 +3,33 @@ using namespace std; -RK4AdvectionKernel::RK4AdvectionKernel(std::shared_ptr grid): grid(grid) { } +RK4AdvectionKernel::RK4AdvectionKernel(std::shared_ptr grid, int dt): grid(grid), dt(dt) { } std::pair RK4AdvectionKernel::advect(int time, double latitude, double longitude) 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); - double lat1 = latitude + metreToDegrees(v1 * 0.5*DT); + double lon1 = longitude + metreToDegrees(u1 * 0.5*dt); + double lat1 = latitude + metreToDegrees(v1 * 0.5*dt); // (u2, v2) = fieldset.UV[time + .5 * particle.dt, particle.depth, lat1, lon1, particle] - auto [u2, v2] = bilinearinterpolate(*grid, time + 0.5 * DT, lat1, lon1); + auto [u2, v2] = bilinearinterpolate(*grid, time + 0.5 * dt, lat1, lon1); // lon2, lat2 = (particle.lon + u2*.5*particle.dt, particle.lat + v2*.5*particle.dt) - double lon2 = longitude + metreToDegrees(u2 * 0.5 * DT); - double lat2 = latitude + metreToDegrees(v2 * 0.5 * DT); + double lon2 = longitude + metreToDegrees(u2 * 0.5 * dt); + double lat2 = latitude + metreToDegrees(v2 * 0.5 * dt); // (u3, v3) = fieldset.UV[time + .5 * particle.dt, particle.depth, lat2, lon2, particle] - auto [u3, v3] = bilinearinterpolate(*grid, time + 0.5 * DT, lat2, lon2); + auto [u3, v3] = bilinearinterpolate(*grid, time + 0.5 * dt, lat2, lon2); // lon3, lat3 = (particle.lon + u3*particle.dt, particle.lat + v3*particle.dt) - double lon3 = longitude + metreToDegrees(u3 * DT); - double lat3 = latitude + metreToDegrees(v3 * DT); + double lon3 = longitude + metreToDegrees(u3 * dt); + double lat3 = latitude + metreToDegrees(v3 * dt); // (u4, v4) = fieldset.UV[time + particle.dt, particle.depth, lat3, lon3, particle] - auto [u4, v4] = bilinearinterpolate(*grid, time + DT, lat3, lon3); + auto [u4, v4] = bilinearinterpolate(*grid, time + dt, lat3, lon3); - double lonFinal = longitude + metreToDegrees((u1 + 2 * u2 + 2 * u3 + u4) / 6.0 * DT); - double latFinal = latitude + metreToDegrees((v1 + 2 * v2 + 2 * v3 + v4) / 6.0 * DT); + double lonFinal = longitude + metreToDegrees((u1 + 2 * u2 + 2 * u3 + u4) / 6.0 * dt); + double latFinal = latitude + metreToDegrees((v1 + 2 * v2 + 2 * v3 + v4) / 6.0 * dt); return {latFinal, lonFinal}; } diff --git a/vtk/src/advection/RK4AdvectionKernel.h b/vtk/src/advection/RK4AdvectionKernel.h index 6b6c88d..ce7d4e3 100644 --- a/vtk/src/advection/RK4AdvectionKernel.h +++ b/vtk/src/advection/RK4AdvectionKernel.h @@ -12,8 +12,9 @@ class RK4AdvectionKernel: public AdvectionKernel { private: std::shared_ptr grid; + int dt; public: - explicit RK4AdvectionKernel(std::shared_ptr grid); + explicit RK4AdvectionKernel(std::shared_ptr grid, int dt); std::pair advect(int time, double latitude, double longitude) const override; }; diff --git a/vtk/src/advection/main.cpp b/vtk/src/advection/main.cpp deleted file mode 100644 index 0e0fc01..0000000 --- a/vtk/src/advection/main.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include - -#include "interpolate.h" -#include "Vel.h" -#include "EulerAdvectionKernel.h" -#include "RK4AdvectionKernel.h" -#include "interpolate.h" - -#define NotAKernelError "Template parameter T must derive from AdvectionKernel" - -using namespace std; - -template -void advectForSomeTime(const UVGrid &uvGrid, const AdvectionKernelImpl &kernel, double latstart, double lonstart, int i, char colour[10]) { - - // Require at compile time that kernel derives from the abstract class AdvectionKernel - static_assert(std::is_base_of::value, NotAKernelError); - - double lat1 = latstart, lon1 = lonstart; - for(int time = 0; time <= 31536000.; time += AdvectionKernel::DT) { -// cout << setprecision(8) << lat1 << "," << setprecision(8) << lon1 << ",end" << i << "," << colour << endl; - try { - auto [templat, templon] = kernel.advect(time, lat1, lon1); - lat1 = templat; - lon1 = templon; - } catch (const out_of_range& e) { - cerr << "broke out of loop!" << endl; - time = 31536001; - } - } - cout << setprecision(8) << latstart << "," << setprecision(8) << lonstart << ",begin" << i << "," << colour << endl; - cout << setprecision(8) << lat1 << "," << setprecision(8) << lon1 << ",end" << i << "," << colour << endl; -} - -void testGridIndexing(const UVGrid *uvGrid) { - int time = 20000; - cout << "=== land === (should all give 0)" << endl; - cout << bilinearinterpolate(*uvGrid, time, 53.80956379699079, -1.6496306344654406) << endl; - cout << bilinearinterpolate(*uvGrid, time, 55.31428895563707, -2.851581041325997) << endl; - cout << bilinearinterpolate(*uvGrid, time, 47.71548983067583, -1.8704054037408626) << endl; - cout << bilinearinterpolate(*uvGrid, time, 56.23521060314398, 8.505979324950573) << endl; - cout << bilinearinterpolate(*uvGrid, time, 53.135645440244375, 8.505979324950573) << endl; - cout << bilinearinterpolate(*uvGrid, time, 56.44761278775708, -4.140629303756164) << endl; - cout << bilinearinterpolate(*uvGrid, time, 52.67625153110339, 0.8978569759455872) << endl; - cout << bilinearinterpolate(*uvGrid, time, 52.07154079279377, 4.627951041411331) << endl; - - cout << "=== ocean === (should give not 0)" << endl; - cout << bilinearinterpolate(*uvGrid, time, 47.43923166616274, -4.985451481829083) << endl; - cout << bilinearinterpolate(*uvGrid, time, 50.68943556852362, -9.306162999561733) << endl; - cout << bilinearinterpolate(*uvGrid, time, 53.70606799886677, -4.518347647034465) << endl; - cout << bilinearinterpolate(*uvGrid, time, 60.57987114267971, -12.208262973672621) << endl; - cout << bilinearinterpolate(*uvGrid, time, 46.532221548197285, -13.408189172582638) << endl; - cout << bilinearinterpolate(*uvGrid, time, 50.92725094937812, 1.3975824052375256) << endl; - cout << bilinearinterpolate(*uvGrid, time, 51.4028921682209, 2.4059571950925203) << endl; - cout << bilinearinterpolate(*uvGrid, time, 53.448445236769004, 0.7996966058017515) << endl; -// cout << bilinearinterpolate(*uvGrid, time, ) << endl; -} - -int main() { - std::shared_ptr uvGrid = std::make_shared(); - - uvGrid->streamSlice(cout, 900); - - auto kernelRK4 = RK4AdvectionKernel(uvGrid); - -// You can use https://maps.co/gis/ to visualise these points - cout << "======= RK4 Integration =======" << endl; - advectForSomeTime(*uvGrid, kernelRK4, 53.53407391652826, 6.274975037862238, 0, "#ADD8E6"); - advectForSomeTime(*uvGrid, kernelRK4, 53.494053820479365, 5.673454142386921, 1, "#DC143C"); - advectForSomeTime(*uvGrid, kernelRK4, 53.49321966653616, 5.681867022043919, 2, "#50C878"); - advectForSomeTime(*uvGrid, kernelRK4, 53.581548701694324, 6.552600066543153, 3, "#FFEA00"); - advectForSomeTime(*uvGrid, kernelRK4, 53.431446729744124, 5.241592961691523, 4, "#663399"); - advectForSomeTime(*uvGrid, kernelRK4, 53.27913608324572, 4.82094897884165, 5, "#FFA500"); - advectForSomeTime(*uvGrid, kernelRK4, 53.18597595482688, 4.767667388308705, 6, "#008080"); - advectForSomeTime(*uvGrid, kernelRK4, 53.01592078792383, 4.6064205160882, 7, "#FFB6C1"); - advectForSomeTime(*uvGrid, kernelRK4, 52.72816940158886, 4.5853883152993635, 8, "#36454F"); // on land - advectForSomeTime(*uvGrid, kernelRK4, 52.56142091881038, 4.502661662924255, 9, "#1E90FF"); // Dodger Blue - advectForSomeTime(*uvGrid, kernelRK4, 52.23202593893584, 4.2825246383181845, 10, "#FFD700"); // Gold - advectForSomeTime(*uvGrid, kernelRK4, 52.08062567609582, 4.112864890830927, 11, "#6A5ACD"); // Slate Blue - advectForSomeTime(*uvGrid, kernelRK4, 51.89497719759734, 3.8114033568921686, 12, "#20B2AA"); // Light Sea Green - advectForSomeTime(*uvGrid, kernelRK4, 51.752848503723634, 3.664177951809339, 13, "#FF69B4"); // Hot Pink - advectForSomeTime(*uvGrid, kernelRK4, 51.64595756528835, 3.626319993352851, 14, "#800080"); // Purple - advectForSomeTime(*uvGrid, kernelRK4, 51.55140730645238, 3.4326152213887986, 15, "#FF4500"); // Orange Red - advectForSomeTime(*uvGrid, kernelRK4, 51.45679776223422, 3.4452813365018384, 16, "#A52A2A"); // Brown - advectForSomeTime(*uvGrid, kernelRK4, 51.41444662720727, 3.4648562416765363, 17, "#4682B4"); // Steel Blue - advectForSomeTime(*uvGrid, kernelRK4, 51.37421261203866, 3.2449264214689455, 18, "#FF6347"); // Tomato - advectForSomeTime(*uvGrid, kernelRK4, 51.29651848898365, 2.9547572241424773, 19, "#008000"); // Green - advectForSomeTime(*uvGrid, kernelRK4, 51.19705098468974, 2.7647654914530024, 20, "#B8860B"); // Dark Goldenrod - advectForSomeTime(*uvGrid, kernelRK4, 51.114719857442665, 2.577076679365129, 21, "#FFC0CB"); // Pink -// advectForSomeTime(*uvGrid, kernelRK4, ,0); - - return 0; -} diff --git a/vtk/src/commands/SpawnPointCallback.cpp b/vtk/src/commands/SpawnPointCallback.cpp index a0f38cd..21a0bcb 100644 --- a/vtk/src/commands/SpawnPointCallback.cpp +++ b/vtk/src/commands/SpawnPointCallback.cpp @@ -9,68 +9,74 @@ #include "../CartographicTransformation.h" -void convertDisplayToWorld(vtkRenderer* renderer, int x, int y, double *worldPos) { - double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; - renderer->SetDisplayPoint(displayPos); - renderer->DisplayToWorld(); - renderer->GetWorldPoint(worldPos); +void convertDisplayToWorld(vtkRenderer *renderer, int x, int y, double *worldPos) { + double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; + renderer->SetDisplayPoint(displayPos); + renderer->DisplayToWorld(); + renderer->GetWorldPoint(worldPos); } void SpawnPointCallback::Execute(vtkObject *caller, unsigned long evId, void *callData) { - // Note the use of reinterpret_cast to cast the caller to the expected type. - auto interactor = reinterpret_cast(caller); + // Note the use of reinterpret_cast to cast the caller to the expected type. + auto interactor = reinterpret_cast(caller); - if (evId == vtkCommand::LeftButtonPressEvent) { - dragging = true; - } - if (evId == vtkCommand::LeftButtonReleaseEvent) { - dragging = false; - } - if (!dragging) { - return; - } + if (evId == vtkCommand::LeftButtonPressEvent) { + dragging = true; + } + if (evId == vtkCommand::LeftButtonReleaseEvent) { + dragging = false; + } + if (!dragging) { + return; + } - int x, y; - interactor->GetEventPosition(x, y); + int x, y; + interactor->GetEventPosition(x, y); - double worldPos[4] = {2, 0 ,0, 0}; - double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; - ren->SetDisplayPoint(displayPos); - ren->DisplayToWorld(); - ren->GetWorldPoint(worldPos); - inverseCartographicProjection->MultiplyPoint(worldPos, worldPos); - cout << "clicked on lon = " << worldPos[0] << " and lat = " << worldPos[1] << endl; + double worldPos[4] = {2, 0, 0, 0}; + double displayPos[3] = {static_cast(x), static_cast(y), 0.0}; + ren->SetDisplayPoint(displayPos); + ren->DisplayToWorld(); + ren->GetWorldPoint(worldPos); + inverseCartographicProjection->MultiplyPoint(worldPos, worldPos); + cout << "clicked on lon = " << worldPos[0] << " and lat = " << worldPos[1] << endl; - vtkIdType id = points->InsertNextPoint(worldPos[0], worldPos[1], 0); - data->SetPoints(points); + vtkIdType id = points->InsertNextPoint(worldPos[0], worldPos[1], 0); + data->SetPoints(points); - vtkSmartPointer vertex = vtkSmartPointer::New(); - vertex->GetPointIds()->SetId(0, id); + vtkSmartPointer vertex = vtkSmartPointer::New(); + vertex->GetPointIds()->SetId(0, id); - vtkSmartPointer vertices = vtkSmartPointer::New(); - vertices->InsertNextCell(vertex); - data->SetVerts(vertices); - ren->GetRenderWindow()->Render(); + vtkSmartPointer vertices = vtkSmartPointer::New(); + vertices->InsertNextCell(vertex); + data->SetVerts(vertices); + ren->GetRenderWindow()->Render(); } -SpawnPointCallback::SpawnPointCallback() : data(nullptr), points(nullptr), inverseCartographicProjection(nullptr) { - inverseCartographicProjection = getCartographicTransformMatrix(); - inverseCartographicProjection->Invert(); -} +SpawnPointCallback::SpawnPointCallback() : data(nullptr), + points(nullptr), + inverseCartographicProjection(nullptr), + uvGrid(nullptr) { } SpawnPointCallback *SpawnPointCallback::New() { return new SpawnPointCallback; } void SpawnPointCallback::setData(const vtkSmartPointer &data) { - this->data = data; + this->data = data; } void SpawnPointCallback::setPoints(const vtkSmartPointer &points) { - this->points = points; + this->points = points; } void SpawnPointCallback::setRen(const vtkSmartPointer &ren) { - this->ren = ren; + this->ren = ren; +} + +void SpawnPointCallback::setUVGrid(const std::shared_ptr &uvGrid) { + this->uvGrid = uvGrid; + inverseCartographicProjection = getCartographicTransformMatrix(uvGrid); + inverseCartographicProjection->Invert(); } diff --git a/vtk/src/commands/SpawnPointCallback.h b/vtk/src/commands/SpawnPointCallback.h index bef6ca4..a4123b2 100644 --- a/vtk/src/commands/SpawnPointCallback.h +++ b/vtk/src/commands/SpawnPointCallback.h @@ -7,26 +7,33 @@ #include #include #include +#include "../advection/UVGrid.h" class SpawnPointCallback : public vtkCallbackCommand { public: - static SpawnPointCallback *New(); - SpawnPointCallback(); + static SpawnPointCallback *New(); - void setPoints(const vtkSmartPointer &points); + SpawnPointCallback(); - void setData(const vtkSmartPointer &data); + void setPoints(const vtkSmartPointer &points); + + void setData(const vtkSmartPointer &data); + + void setRen(const vtkSmartPointer &ren); + + void setUVGrid(const std::shared_ptr &uvGrid); - void setRen(const vtkSmartPointer &ren); private: - vtkSmartPointer data; - vtkSmartPointer points; - vtkSmartPointer ren; - vtkSmartPointer inverseCartographicProjection; + vtkSmartPointer data; + vtkSmartPointer points; + vtkSmartPointer ren; + std::shared_ptr uvGrid; + vtkSmartPointer inverseCartographicProjection; - void Execute(vtkObject *caller, unsigned long evId, void *callData) override; - bool dragging = false; + void Execute(vtkObject *caller, unsigned long evId, void *callData) override; + + bool dragging = false; }; diff --git a/vtk/src/commands/TimerCallbackCommand.cpp b/vtk/src/commands/TimerCallbackCommand.cpp index 8e91b58..6fad2ca 100644 --- a/vtk/src/commands/TimerCallbackCommand.cpp +++ b/vtk/src/commands/TimerCallbackCommand.cpp @@ -38,3 +38,7 @@ void TimerCallbackCommand::setProgram(Program *program) { void TimerCallbackCommand::setPaused(const bool val) { this->paused = val; } + +void TimerCallbackCommand::setDt(int dt) { + this->dt = dt; +} diff --git a/vtk/src/commands/TimerCallbackCommand.h b/vtk/src/commands/TimerCallbackCommand.h index 2ff65ea..7123f4d 100644 --- a/vtk/src/commands/TimerCallbackCommand.h +++ b/vtk/src/commands/TimerCallbackCommand.h @@ -13,6 +13,8 @@ public: void setProgram(Program *program); void setPaused(const bool val); + void setDt(int dt); + private: int time; int dt; diff --git a/vtk/src/layers/EGlyphLayer.cpp b/vtk/src/layers/EGlyphLayer.cpp index afcb4b3..59301b0 100644 --- a/vtk/src/layers/EGlyphLayer.cpp +++ b/vtk/src/layers/EGlyphLayer.cpp @@ -50,9 +50,8 @@ void EGlyphLayer::readCoordinates() { int lonIndex = 0; for (double lon: uvGrid->lons) { auto [u, v] = (*uvGrid)[0, latIndex, lonIndex]; - direction->SetTuple3(i, 2*v, 2*u, 0); + direction->SetTuple3(i, 5*u, 5*v, 0); points->InsertPoint(i++, lon, lat, 0); - // see also https://vtk.org/doc/nightly/html/classvtkPolyDataMapper2D.html lonIndex++; } latIndex++; @@ -61,7 +60,7 @@ void EGlyphLayer::readCoordinates() { this->data->GetPointData()->AddArray(this->direction); this->data->GetPointData()->SetActiveVectors("direction"); - vtkSmartPointer transformFilter = createCartographicTransformFilter(); + vtkSmartPointer transformFilter = createCartographicTransformFilter(uvGrid); transformFilter->SetInputData(data); vtkNew arrowSource; @@ -101,7 +100,8 @@ void EGlyphLayer::updateData(int t) { for (int lat = 0; lat < uvGrid->latSize; lat++) { for (int lon = 0; lon < uvGrid->lonSize; lon++) { auto [u, v] = (*uvGrid)[t/3600, lat, lon]; - this->direction->SetTuple3(i, 5*v, 5*u, 0); // FIXME: fetch data from file. + // TODO: The 5*v stuff should really be a filter transform + this->direction->SetTuple3(i, 5*u, 5*v, 0); i++; } } diff --git a/vtk/src/layers/LGlyphLayer.cpp b/vtk/src/layers/LGlyphLayer.cpp index 9b0840a..311c49c 100644 --- a/vtk/src/layers/LGlyphLayer.cpp +++ b/vtk/src/layers/LGlyphLayer.cpp @@ -23,6 +23,7 @@ vtkSmartPointer LGlyphLayer::createSpawnPointCallback() { newPointCallBack->setData(data); newPointCallBack->setPoints(points); newPointCallBack->setRen(ren); + newPointCallBack->setUVGrid(uvGrid); return newPointCallBack; } @@ -31,7 +32,7 @@ vtkSmartPointer 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::unique_ptr advectionKernel) { +LGlyphLayer::LGlyphLayer(std::shared_ptr uvGrid, std::unique_ptr advectionKernel) { this->ren = vtkSmartPointer::New(); this->ren->SetLayer(2); @@ -40,13 +41,12 @@ LGlyphLayer::LGlyphLayer(std::unique_ptr advectionKernel) { this->data->SetPoints(this->points); advector = std::move(advectionKernel); + this->uvGrid = uvGrid; auto camera = createNormalisedCamera(); ren->SetActiveCamera(camera); - auto transform = createCartographicTransformFilter(); - - vtkSmartPointer transformFilter = createCartographicTransformFilter(); + vtkSmartPointer transformFilter = createCartographicTransformFilter(uvGrid); transformFilter->SetInputData(data); vtkNew circleSource; @@ -97,10 +97,7 @@ void LGlyphLayer::updateData(int t) { } void LGlyphLayer::addObservers(vtkSmartPointer interactor) { - auto newPointCallBack = vtkSmartPointer::New(); - newPointCallBack->setData(data); - newPointCallBack->setPoints(points); - newPointCallBack->setRen(ren); + auto newPointCallBack = createSpawnPointCallback(); interactor->AddObserver(vtkCommand::LeftButtonPressEvent, newPointCallBack); interactor->AddObserver(vtkCommand::LeftButtonReleaseEvent, newPointCallBack); interactor->AddObserver(vtkCommand::MouseMoveEvent, newPointCallBack); diff --git a/vtk/src/layers/LGlyphLayer.h b/vtk/src/layers/LGlyphLayer.h index 1a8dc0f..48d3108 100644 --- a/vtk/src/layers/LGlyphLayer.h +++ b/vtk/src/layers/LGlyphLayer.h @@ -15,13 +15,12 @@ private: vtkSmartPointer points; vtkSmartPointer data; std::unique_ptr advector; - - + std::shared_ptr uvGrid; public: /** Constructor. */ - LGlyphLayer(std::unique_ptr advectionKernel); + LGlyphLayer(std::shared_ptr uvGrid, std::unique_ptr advectionKernel); /** This function spoofs a few points in the dataset. Mostly used for testing. */ diff --git a/vtk/src/main.cpp b/vtk/src/main.cpp index c4ba1e7..7486eb1 100644 --- a/vtk/src/main.cpp +++ b/vtk/src/main.cpp @@ -18,15 +18,16 @@ using namespace std; +#define DT 60 * 60 // 60 sec/min * 60 mins int main() { shared_ptr uvGrid = std::make_shared(); - auto kernelRK4 = make_unique(uvGrid); + auto kernelRK4 = make_unique(uvGrid, DT); - auto l = new LGlyphLayer(move(kernelRK4)); + auto l = new LGlyphLayer(uvGrid, move(kernelRK4)); // l->spoofPoints(); - Program *program = new Program(); + Program *program = new Program(DT); program->addLayer(new BackgroundImage("../../../../data/map_661-661.png")); program->addLayer(new EGlyphLayer(uvGrid)); program->addLayer(l);