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 );
auto degree = vtkMath::DegreesFromRadians( radius );
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->AddActor( actor );
renderer->AddActor( axesActor );
renderer->SetBackground( 0, 0, 0 );
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
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 <vtkSTLReader.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->SetRadius( 1 );
sphere1->Update();
vtkSmartPointer<vtkSphereSource> sphere2 =
vtkSmartPointer<vtkSphereSource>::New();
sphere2->SetCenter( 0, 0, 0 );
sphere2->SetRadius( 1 );
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->AddActor(actor);
renderer->SetBackground( 0, 0, 0 );
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
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->SetRadius( 1 );
sphere1->Update();
vtkSmartPointer<vtkSphereSource> sphere2 =
vtkSmartPointer<vtkSphereSource>::New();
sphere2->SetCenter( 0, 0, 0 );
sphere2->SetRadius( 1 );
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 );