Files
interactive-track-and-trace/particle-track-and-trace/src/CartographicTransformation.cpp
T
2024-05-08 19:51:41 +02:00

92 lines
3.5 KiB
C++

#include "CartographicTransformation.h"
#include <vtkMatrix4x4.h>
#include <vtkTransform.h>
#include <vtkTransformFilter.h>
#include <vtkGeoProjection.h>
#include <vtkGeoTransform.h>
#include <vtkGeneralTransform.h>
vtkSmartPointer<vtkCamera> createNormalisedCamera() {
vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
camera->ParallelProjectionOn(); // Enable parallel projection
camera->SetPosition(0, 0, 1000); // Place the camera above the center
camera->SetFocalPoint(0, 0, 0); // Look at the center
camera->SetViewUp(0, 1, 0); // Set the up vector to be along the Y-axis
camera->SetParallelScale(1); // x,y in [-1, 1]
return camera;
}
// Assumes Normalised camera is used
vtkSmartPointer<vtkTransformFilter> createCartographicTransformFilter(const std::shared_ptr<UVGrid> uvGrid) {
auto proj = vtkSmartPointer<vtkGeoProjection>::New();
proj->SetName("merc");
auto geoTransform = vtkSmartPointer<vtkGeoTransform>::New();
geoTransform->SetDestinationProjection(proj);
const double XMin = uvGrid->lonMin();
const double XMax = uvGrid->lonMax();
const double YMin = uvGrid->latMin();
const double YMax = uvGrid->latMax();
double bottomLeft[3] = {XMin, YMin, 0};
double topRight[3] = {XMax, YMax, 0};
geoTransform->TransformPoint(bottomLeft, bottomLeft);
geoTransform->TransformPoint(topRight, topRight);
double width = topRight[0] - bottomLeft[0];
double height = topRight[1] - bottomLeft[1];
auto scaleIntoNormalisedSpace = vtkSmartPointer<vtkTransform>::New();
scaleIntoNormalisedSpace->Scale(2 / (width), 2 / (height), 1);
scaleIntoNormalisedSpace->Translate(-(bottomLeft[0] + topRight[0]) / 2, -(bottomLeft[1] + topRight[1]) / 2, 0);
auto totalProjection = vtkSmartPointer<vtkGeneralTransform>::New();
totalProjection->Identity();
totalProjection->Concatenate(scaleIntoNormalisedSpace);
totalProjection->Concatenate(geoTransform);
vtkSmartPointer<vtkTransformFilter> transformFilter = vtkSmartPointer<vtkTransformFilter>::New();
transformFilter->SetTransform(totalProjection);
return transformFilter;
}
vtkSmartPointer<vtkTransformFilter> createInverseCartographicTransformFilter(const std::shared_ptr<UVGrid> uvGrid) {
auto proj = vtkSmartPointer<vtkGeoProjection>::New();
proj->SetName("merc");
auto geoTransform = vtkSmartPointer<vtkGeoTransform>::New();
geoTransform->SetDestinationProjection(proj);
const double XMin = uvGrid->lonMin();
const double XMax = uvGrid->lonMax();
const double YMin = uvGrid->latMin();
const double YMax = uvGrid->latMax();
double bottomLeft[3] = {XMin, YMin, 0};
double topRight[3] = {XMax, YMax, 0};
geoTransform->TransformPoint(bottomLeft, bottomLeft);
geoTransform->TransformPoint(topRight, topRight);
geoTransform->Inverse();
double width = topRight[0] - bottomLeft[0];
double height = topRight[1] - bottomLeft[1];
auto scaleIntoNormalisedSpace = vtkSmartPointer<vtkTransform>::New();
scaleIntoNormalisedSpace->Scale(2 / (width), 2 / (height), 1);
scaleIntoNormalisedSpace->Translate(-(bottomLeft[0] + topRight[0]) / 2, -(bottomLeft[1] + topRight[1]) / 2, 0);
scaleIntoNormalisedSpace->Inverse();
auto totalProjection = vtkSmartPointer<vtkGeneralTransform>::New();
totalProjection->Identity();
totalProjection->Concatenate(geoTransform);
totalProjection->Concatenate(scaleIntoNormalisedSpace);
vtkSmartPointer<vtkTransformFilter> transformFilter = vtkSmartPointer<vtkTransformFilter>::New();
transformFilter->SetTransform(totalProjection);
return transformFilter;
}