### Calculate Rotate Angle And Asix Between Two Vectors

``````    Point vecA( 1, 0, 0 );
Point vecB( -1, 1, 0 );
vecB.Unit();

Point crossVec = vecA ^ vecB;
auto dotValue = vecA.Dot( vecB );
auto radius = std::acos( dotValue );

cout << "degree: " << degree << endl;
cout << "crossVec: " << crossVec[0] << ", " << crossVec[1] << ", " << crossVec[2] << endl;
``````

### Calculate Model’s Size In Local Coordinate System

``````#include "point.hpp"

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

using namespace std;

void CalculateBboxInLocalSystem
(
double *bds,
vtkPolyData *polyData,
vtkSmartPointer<vtkTransform> localXFM
)
{
vtkSPtrNew( transFilter, vtkTransformFilter );
transFilter->SetInputData( polyData );
transFilter->SetTransform( localXFM );
transFilter->Update();
vtkSPtrNew( localPd, vtkPolyData );
localPd->DeepCopy( transFilter->GetOutput() );
localPd->ComputeBounds();
double *result = localPd->GetBounds();
for( int i = 0; i < 6; ++i )
{
bds[i] = result[i];
}
}

vtkSmartPointer<vtkTransform> CreateLocalTrans
(
Point origin,
Point xDir,
Point yDir
)
{
vtkSPtrNew( resultTrans, vtkTransform );
Point zDir = xDir ^ yDir;
zDir.Unit();

double elements1[16] = { xDir[0], xDir[1], xDir[2], 0,
yDir[0], yDir[1], yDir[2], 0,
zDir[0], zDir[1], zDir[2], 0,
0, 0, 0, 1 };

resultTrans->Concatenate(elements1);     //rotation

double elements2[16] = { 1, 0, 0, -origin[0],
0, 1, 0, -origin[1],
0, 0, 1, -origin[2],
0, 0, 0, 1 };

resultTrans->Concatenate(elements2);    //translation
resultTrans->Update();

return resultTrans;
}

int main()
{
vtkSPtrNew( source, vtkConeSource );
source->Update();
auto *pd = source->GetOutput();
pd->ComputeBounds();
double bds[6];
pd->GetBounds( bds );
cout << "bds: " << bds[0] << ", " << bds[1] << ", " << bds[2] << ", " << bds[3] << ", "
<< bds[4] << ", " << bds[5] << endl;

vtkSPtrNew( trans0, vtkTransform );
trans0->RotateZ( -45 );
trans0->Update();

vtkSPtrNew( transFilter, vtkTransformFilter );
transFilter->SetInputData( pd );
transFilter->SetTransform( trans0 );
transFilter->Update();

vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputData( transFilter->GetPolyDataOutput() );

vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );

// ========== get local's size ============
Point xDir( 1, -1, 0 );
xDir.Unit();
Point yDir( 1, 1, 0 );
yDir.Unit();
vtkSPtr<vtkTransform> localXFM = CreateLocalTrans( Point( 0, 0, 0 ), xDir, yDir);
CalculateBboxInLocalSystem( bds, transFilter->GetPolyDataOutput(), localXFM );
cout << "bds: " << bds[0] << ", " << bds[1] << ", " << bds[2] << ", " << bds[3] << ", "
<< bds[4] << ", " << bds[5] << endl;

vtkSPtrNew( axesActor, vtkAxesActor );
axesActor->SetTotalLength( 3, 3, 3 );
axesActor->SetUserTransform( trans0 );

vtkSPtrNew( renderer, vtkRenderer );
renderer->SetBackground( 0, 0, 0 );

vtkSPtrNew( renderWindow, vtkRenderWindow );

vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );

renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
``````

output:

``````bds: -0.5, 0.5, -0.5, 0.5, -0.433013, 0.433013
bds: -0.5, 0.5, -0.5, 0.5, -0.433013, 0.433013
``````

Relevant link: VTK: Find Bounding Shell In Local Coordinate System

### Boolean Operation For Mesh

We can use the third party library to do boolean computation for mesh, relvant link: vtk bool.
But I use vtkBooleanOperationPolyDataFilter in the following simple scene, subtract center sphere by the left one.

``````#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkClipClosedSurface.h>
#include <vtkFillHolesFilter.h>
#include <vtkPlane.h>
#include <vtkTransform.h>
#include <vtkPlaneCollection.h>
#include <vtkBooleanOperationPolyDataFilter.h>

#include "point.hpp"

#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();

using namespace std;

int main()
{
vtkSmartPointer<vtkBooleanOperationPolyDataFilter> boolFilter =
vtkSmartPointer<vtkBooleanOperationPolyDataFilter>::New();

vtkSmartPointer<vtkSphereSource> sphere1 =
vtkSmartPointer<vtkSphereSource>::New();
sphere1->SetCenter( -1, 0, 0 );
sphere1->Update();

vtkSmartPointer<vtkSphereSource> sphere2 =
vtkSmartPointer<vtkSphereSource>::New();
sphere2->SetCenter( 0, 0, 0 );
sphere2->Update();

boolFilter->SetInputData( 1, sphere1->GetOutput() );
boolFilter->SetInputData( 0, sphere2->GetOutput() );
boolFilter->SetOperationToDifference();
boolFilter->Update();

vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputConnection( boolFilter->GetOutputPort() );
mapper->SetScalarVisibility( false );

vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );

vtkSPtrNew( renderer, vtkRenderer );
renderer->SetBackground( 0, 0, 0 );

vtkSPtrNew( renderWindow, vtkRenderWindow );

vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );

renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
``````

### Found Intersection Circle Of Two Models

``````    vtkSmartPointer<vtkSphereSource> sphere1 =
vtkSmartPointer<vtkSphereSource>::New();
sphere1->SetCenter( -1, 0, 0 );
sphere1->Update();

vtkSmartPointer<vtkSphereSource> sphere2 =
vtkSmartPointer<vtkSphereSource>::New();
sphere2->SetCenter( 0, 0, 0 );
sphere2->Update();

vtkSPtrNew(intersectionPolyDataFilter, vtkIntersectionPolyDataFilter);
intersectionPolyDataFilter->SetInputDataObject(0, sphere1->GetOutput());
intersectionPolyDataFilter->SetInputDataObject(1, sphere2->GetOutput());
intersectionPolyDataFilter->Update();

vtkSPtr<vtkPolyData> intersectPd = intersectionPolyDataFilter->GetOutput();

vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputData( intersectPd );
``````
Categories: AlgorithmVTK

Article Rating
Subscribe
Notify of