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;
}


0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments

Content Summary
: Input your strings, the tool can get a brief summary of the content for you.

X
0
Would love your thoughts, please comment.x
()
x