We want to know the height of the above cone, there is the precondition that there is a red sphere in the center of the cone and we assume that we can’t get the height from multiplying the length of the vector both red spheres forms by 2. The original scene can be built by the following code snippet.
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
using namespace std;
int main()
{
vtkSPtrNew( cone, vtkConeSource );
cone->SetHeight( 5 );
cone->SetRadius( 2 );
cone->Update();
vtkSPtrNew( mapper, vtkPolyDataMapper );
mapper->SetInputConnection( cone->GetOutputPort() );
vtkSPtrNew( actor, vtkActor );
actor->SetMapper( mapper );
PointStruct p0( 2.5, 0, 0 );
PointStruct p1( 0, 0, 0 );
vtkSPtrNew( sphere0, vtkSphereSource );
sphere0->SetCenter( p0.point );
sphere0->SetRadius( 0.2 );
sphere0->Update();
vtkSPtrNew( sMapper0, vtkPolyDataMapper );
sMapper0->SetInputData( sphere0->GetOutput() );
vtkSPtrNew( sActor0, vtkActor );
sActor0->SetMapper( sMapper0 );
sActor0->GetProperty()->SetColor( 1, 0, 0 );
vtkSPtrNew( sphere1, vtkSphereSource );
sphere1->SetCenter( p1.point );
sphere1->SetRadius( 0.2 );
sphere1->Update();
vtkSPtrNew( sMapper1, vtkPolyDataMapper );
sMapper1->SetInputData( sphere1->GetOutput() );
vtkSPtrNew( sActor1, vtkActor );
sActor1->SetMapper( sMapper1 );
sActor1->GetProperty()->SetColor( 1, 0, 0 );
vtkSPtrNew( renderer, vtkRenderer );
renderer->AddActor(actor);
renderer->AddActor( sActor0 );
renderer->AddActor( sActor1 );
renderer->SetBackground( 0, 0, 0 );
vtkSPtrNew( transform, vtkTransform );
actor->SetUserTransform( transform );
sActor0->SetUserTransform( transform );
sActor1->SetUserTransform( transform );
transform->RotateZ( 30 );
vtkSPtrNew( renderWindow, vtkRenderWindow );
renderWindow->AddRenderer( renderer );
vtkSPtrNew( renderWindowInteractor, vtkRenderWindowInteractor );
renderWindowInteractor->SetRenderWindow( renderWindow );
renderer->ResetCamera();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
Let’s create a local transform for the cone and use it to calculate cone’s size, it’s equal to put it horizontally and compute bounds.
vtkSPtr<vtkTransform> CreateLocalTrans(PointStruct origin, PointStruct xDir, PointStruct yDir)
{
vtkSPtrNew( resultTrans, vtkTransform );
PointStruct 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;
}
Make local transform work in main function to give us the height of the cone.
int main()
{
//...
p0 = PointStruct( sActor0->GetCenter() );
p1 = PointStruct( sActor1->GetCenter() );
cout << p0 << endl;
cout << p1 << endl;
PointStruct xDir = p0 - p1;
xDir.Unit();
PointStruct zDir( 0, 0, 1 );
PointStruct yDir = zDir ^ xDir;
yDir.Unit();
vtkSPtr<vtkTransform> localTrans = CreateLocalTrans( PointStruct(0, 0, 0), xDir, yDir );
// we assume that the cone is really crooked
vtkSPtrNew( transformFilter0, vtkTransformFilter );
transformFilter0->SetInputData( cone->GetOutput() );
transformFilter0->SetTransform( transform );
transformFilter0->Update();
// use localTrans to make it horizontal
vtkSPtrNew( transformFilter, vtkTransformFilter );
transformFilter->SetInputData( transformFilter0->GetOutput() );
transformFilter->SetTransform( localTrans );
transformFilter->Update();
transformFilter->GetOutput()->ComputeBounds();
double *bounds = transformFilter->GetOutput()->GetBounds();
cout << "bounds: (" << bounds[0] << ", " << bounds[1] << ", " << bounds[2]
<< ", " << bounds[3] << ", " << bounds[4] << ", " << bounds[5] << ")\n";
cout << "height: " << bounds[1] - bounds[0] << endl;
//...
}
Output:
PointStruct [2.16506, 1.25, 0]
PointStruct [0, 0, 0]
bounds: (-2.5, 2.5, -2, 2, -1.73205, 1.73205)
height: 5
Header files we need in the program.
#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 <vtkTransform.h>
#include <vtkSphereSource.h>
#include <vtkProperty.h>
#include "../share/tool.h"