#ifndef VTKHSWARRORWIDGET_H
#define VTKHSWARRORWIDGET_H
/*
* ModuleName: vtkRoboArrowWidget
* Description: 實現箭頭
* Author: hsw
* Date: 2020-03-22
*
*/
#include <vtkSmartPointer.h>
#include <vtkArrowSource.h>
#include <vtkDataSetMapper.h>
#include <vtkMinimalStandardRandomSequence.h>
#include <vtkMatrix4x4.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
class vtkHSWArrorWidget
{
public:
vtkHSWArrorWidget();
~vtkHSWArrorWidget();
public:
vtkSmartPointer<vtkDataSetMapper> createArrow(double* start, double* end);
private:
vtkSmartPointer<vtkArrowSource> _arrowSource;
vtkSmartPointer<vtkDataSetMapper> _arrowMapper;
};
#endif // VTKHSWARRORWIDGET_H
#include "vtkhswarrorwidget.h"
vtkHSWArrorWidget::vtkHSWArrorWidget()
{
// TODO...
}
vtkHSWArrorWidget::~vtkHSWArrorWidget()
{
// TODO...
}
vtkSmartPointer<vtkDataSetMapper> vtkHSWArrorWidget::createArrow(double* start, double* end)
{
_arrowSource = vtkSmartPointer<vtkArrowSource>::New();
// Compute a basis
double normalizedX[3];
double normalizedY[3];
double normalizedZ[3];
// The X axis is a vector from start to end
vtkMath::Subtract(end, start, normalizedX);
double length = vtkMath::Norm(normalizedX);
vtkMath::Normalize(normalizedX);
// The Z axis is an arbitrary vector cross X
vtkSmartPointer<vtkMinimalStandardRandomSequence> rng =
vtkSmartPointer<vtkMinimalStandardRandomSequence>::New();
rng->SetSeed(8775070);
double arbitrary[3];
for (auto i = 0; i < 3; ++i)
{
rng->Next();
arbitrary[i] = rng->GetRangeValue(-10, 10);
}
vtkMath::Cross(normalizedX, arbitrary, normalizedZ);
vtkMath::Normalize(normalizedZ);
// The Y axis is Z cross X
vtkMath::Cross(normalizedZ, normalizedX, normalizedY);
vtkSmartPointer<vtkMatrix4x4> matrix =
vtkSmartPointer<vtkMatrix4x4>::New();
// Create the direction cosine matrix
matrix->Identity();
for (auto i = 0; i < 3; i++)
{
matrix->SetElement(i, 0, normalizedX[i]);
matrix->SetElement(i, 1, normalizedY[i]);
matrix->SetElement(i, 2, normalizedZ[i]);
}
// Apply the transforms
vtkSmartPointer<vtkTransform> transform =
vtkSmartPointer<vtkTransform>::New();
transform->Translate(start);
transform->Concatenate(matrix);
transform->Scale(length, length, length);
// Transform the polydata
vtkSmartPointer<vtkTransformPolyDataFilter> transformPD =
vtkSmartPointer<vtkTransformPolyDataFilter>::New();
transformPD->SetTransform(transform);
transformPD->SetInputConnection(_arrowSource->GetOutputPort());
_arrowMapper = vtkSmartPointer<vtkDataSetMapper>::New();
_arrowMapper->SetInputConnection(transformPD->GetOutputPort());
return _arrowMapper;
}