The post is based on https://www.weiy.city/2021/11/vtk-rotate-vector-to-special-direction/.
We will rotate the three axes of the world coordinate system to particular directions.
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkTransform.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkAxesActor.h>
#include "../point.hpp"
using namespace std;
double AngleBeteewnTwoVector( Point vec0, Point vec1 )
{
auto radians = vtkMath::AngleBetweenVectors( vec0.point, vec1.point );
auto degree = vtkMath::DegreesFromRadians( radians );
return degree;
}
int main()
{
Point directionX(1, 0, 1), directionY(-1, 0, 1), directionZ(0, -1, 0); // new axis
Point dirX(1, 0, 0), dirY(0, 1, 0), dirZ(0, 0, 1); // standard axis
Point dirRotateX, dirRotateY, dirRotateZ;
// =========== start ==============
vtkSmartPointer<vtkTransform> trans = vtkSmartPointer<vtkTransform>::New();
double angleX = AngleBeteewnTwoVector(dirX,directionX );
double err = 0.0001;
if (fabs(angleX) > err )
{
if (fabs(angleX - 180) < err)
dirRotateX = dirZ;
else
dirRotateX = dirX^directionX;
dirRotateX.Unit();
trans->RotateWXYZ(angleX, dirRotateX[0], dirRotateX[1], dirRotateX[2]);
trans->Update();
}
trans->InternalTransformVector(dirY.point, dirY.point);
double angleY = AngleBeteewnTwoVector(dirY, directionY);
if (fabs(angleY) > err)
{
if (fabs(angleY - 180) < err)
dirRotateY = directionX;
else
dirRotateY = dirY^directionY;
dirRotateY.Unit();
trans->Identity();
trans->RotateWXYZ(angleY, dirRotateY[0], dirRotateY[1], dirRotateY[2]);
trans->RotateWXYZ(angleX, dirRotateX[0], dirRotateX[1], dirRotateX[2]);
trans->Update();
}
trans->InternalTransformVector(dirZ.point, dirZ.point);
double angleZ = AngleBeteewnTwoVector(dirZ, directionZ);
if (fabs(angleZ) > err)
{
if (fabs(angleZ - 180) < err)
dirRotateZ = directionY;
else
dirRotateZ = dirZ^directionZ;
dirRotateZ.Unit();
trans->Identity();
trans->RotateWXYZ(angleX, dirRotateX[0], dirRotateX[1], dirRotateX[2]);
trans->RotateWXYZ(angleY, dirRotateY[0], dirRotateY[1], dirRotateY[2]);
trans->RotateWXYZ(angleZ, dirRotateZ[0], dirRotateZ[1], dirRotateZ[2]);
trans->Update();
}
// =========== end ==============
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
axes->SetTotalLength( 1, 1, 1 ); // change length of three axis
axes->SetUserTransform( trans );
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(axes);
renderer->SetBackground( 0, 0, 0 );
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}