[VTK] VTK drawing arrows - support setting starting point, direction and length

VTK drawing arrows - support setting start point, direction and length

At present, many cases about VTK drawing arrows on the Internet are drawn with vtkArrowSource. In fact, it is impossible to set the specific coordinate starting point and direction of the arrow, which is not useful. If you want to create an arrow that freely sets the coordinates and direction of the starting point, it requires a troublesome operation on VTK, as follows:


method

  1. You need to create a vtkPolyData containing only one vertex by yourself. You need to use vtkVertex instead of vtkSphereSource.
  2. It is necessary to specify the vertex normal vector (that is, the orientation of the vector) and the specified vector length (realized by scalar vertex scalar) for the self-built vtkPolyData.
  3. Use vtkArrowSource to display the normal vector of vtkPolyData.

the code

Implemented with two functions: first execute the CreateSingleVectorArrowData function, and then use the result as the input to execute the function

  • CreateSingleVectorArrowData function: create arrow data
  • Input: origin starting point coordinates, target end point facing coordinates, length arrow length
  • Output: vtkPolyData arrow geometry data
//@param origin和target都是三元素的一维数组double[3],length决定可视化向量的长度
vtkPolyData* CreateSingleVectorArrowData(double* origin, double* target, double length)
{
    
    
	vtkMath* math;
	math->Subtract(target, origin, target); //计算向量的朝向 target=target-origin

	vtkPoints* points = vtkPoints::New();  //记录起点坐标
	points->InsertNextPoint(origin);

	vtkVertex *vertex = vtkVertex::New();  //建立起点的拓扑(不建立拓扑的话是不行的)
	vertex->GetPointIds()->SetNumberOfIds(points->GetNumberOfPoints());
	for (int i = 0; i < points->GetNumberOfPoints(); i++) {
    
    
		vertex->GetPointIds()->SetId(i, i); //setId(拓扑的id, 顶点的id)
	}

	vtkDoubleArray* normals = vtkDoubleArray::New();  //创建法向量属性,存入向量的朝向target
	normals->SetNumberOfComponents(3);
	normals->InsertNextTuple(target);

	vtkDoubleArray* scalars = vtkDoubleArray::New();  //创建标量属性,存入向量的长度length
	scalars->SetNumberOfComponents(1);
	scalars->SetName("scalars");
	scalars->InsertNextTuple1(length);

	vtkSmartPointer<vtkCellArray> vertices =
		vtkSmartPointer<vtkCellArray>::New();
	vertices->InsertNextCell(vertex);	//将建立的拓扑用vtkCellArray封装,用于赋予vtkPolyData

	vtkPolyData *polydata = vtkPolyData::New();  //创建几何实体
	polydata->SetPoints(points);	//赋予起点
	polydata->SetVerts(vertices);	//赋予拓扑
	polydata->GetPointData()->SetNormals(normals);	//赋予向量朝向 
	polydata->GetPointData()->SetScalars(scalars);	//赋予向量长度
	return polydata;
}
  • GenerateNormalsArrow function: Create specific arrow geometry entities for arrow geometry data
  • Input: polyData Arrow data from the output of the CreateSingleVectorArrowData function
  • Output: vtkPolyData can be used to display arrow geometric entities
vtkPolyData* GenerateNormalsArrow(vtkPolyData* polyData)
{
    
    
	vtkArrowSource *arrow = vtkArrowSource::New();
	arrow->Update();

	vtkGlyph3D* glyph = vtkGlyph3D::New();
	glyph->SetInputData(polyData);
	glyph->SetSourceData(arrow->GetOutput());
	glyph->SetScaleFactor(0.1);
	glyph->SetVectorModeToUseNormal();
	glyph->Update();
	return glyph->GetOutput();
}

Arrows can be displayed by constructing the vtkPolyData output of GenerateNormalsArrow into a vtkActor.


result

  • Starting point (0, 0, 0), towards (1, 1, 1), length 20:
    insert image description here

  • Join the coordinate system:
    insert image description here

Guess you like

Origin blog.csdn.net/qq_37366618/article/details/124037374