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"
Categories: VTK

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
A prohibited operation
0
Would love your thoughts, please comment.x
()
x