如何在VTK中根据线条朝向同时为多线条单元显示标签?
在VTK中为线条单元添加方向标签
要给VTK中的线条单元按方向添加标签,最简便的方式是通过vtkLabeledDataMapper结合vtkActor2D实现,核心是先计算每个线条单元的中点(标签放置位置)和方向角度(控制标签朝向),再将这些数据关联到标签映射器中。
以下是VC++环境下的完整代码示例:
#include <vtkSmartPointer.h> #include <vtkPolyData.h> #include <vtkPoints.h> #include <vtkCellArray.h> #include <vtkLabeledDataMapper.h> #include <vtkActor2D.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkDoubleArray.h> #include <vtkMath.h> #include <vtkCoordinate.h> int main() { // 1. 创建示例线条数据(两条不同方向的线段) vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->InsertNextPoint(0, 0, 0); points->InsertNextPoint(2, 1, 0); points->InsertNextPoint(1, 2, 0); points->InsertNextPoint(3, 3, 0); vtkSmartPointer<vtkCellArray> lines = vtkSmartPointer<vtkCellArray>::New(); vtkIdType line1[2] = {0, 1}; lines->InsertNextCell(2, line1); vtkIdType line2[2] = {2, 3}; lines->InsertNextCell(2, line2); vtkSmartPointer<vtkPolyData> lineData = vtkSmartPointer<vtkPolyData>::New(); lineData->SetPoints(points); lineData->SetLines(lines); // 2. 计算每个线条单元的中点与方向角度,存储为标签用的点数据 vtkSmartPointer<vtkPoints> labelPoints = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkDoubleArray> labelAngles = vtkSmartPointer<vtkDoubleArray>::New(); labelAngles->SetName("LabelAngle"); vtkIdType numLines = lineData->GetNumberOfLines(); for (vtkIdType i = 0; i < numLines; ++i) { vtkCell* line = lineData->GetCell(i); double p1[3], p2[3]; lineData->GetPoint(line->GetPointId(0), p1); lineData->GetPoint(line->GetPointId(1), p2); // 计算线条中点坐标 double midPoint[3]; midPoint[0] = (p1[0] + p2[0]) / 2.0; midPoint[1] = (p1[1] + p2[1]) / 2.0; midPoint[2] = (p1[2] + p2[2]) / 2.0; labelPoints->InsertNextPoint(midPoint); // 计算线条与X轴的夹角,作为标签旋转角度 double dirX = p2[0] - p1[0]; double dirY = p2[1] - p1[1]; double angle = vtkMath::DegreesFromRadians(atan2(dirY, dirX)); labelAngles->InsertNextValue(angle); } vtkSmartPointer<vtkPolyData> labelData = vtkSmartPointer<vtkPolyData>::New(); labelData->SetPoints(labelPoints); labelData->GetPointData()->AddArray(labelAngles); // 3. 配置标签映射器与2D Actor vtkSmartPointer<vtkLabeledDataMapper> labelMapper = vtkSmartPointer<vtkLabeledDataMapper>::New(); labelMapper->SetInputData(labelData); // 这里用线条索引作为标签内容,可替换为自定义文本 labelMapper->SetLabelModeToLabelIds(); // 绑定旋转角度数组,让标签顺着线条方向显示 labelMapper->SetOrientationArrayName("LabelAngle"); labelMapper->SetOrientationModeToUsePointData(); vtkSmartPointer<vtkActor2D> labelActor = vtkSmartPointer<vtkActor2D>::New(); labelActor->SetMapper(labelMapper); // 调整标签样式 labelMapper->GetTextProperty()->SetFontSize(12); labelMapper->GetTextProperty()->SetColor(1.0, 0.0, 0.0); // 4. 搭建渲染管线 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renderWindow); // 添加线条Actor vtkSmartPointer<vtkActor> lineActor = vtkSmartPointer<vtkActor>::New(); vtkSmartPointer<vtkPolyDataMapper> lineMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); lineMapper->SetInputData(lineData); lineActor->SetMapper(lineMapper); lineActor->GetProperty()->SetColor(0.0, 0.0, 1.0); renderer->AddActor(lineActor); renderer->AddActor(labelActor); renderer->SetBackground(1.0, 1.0, 1.0); renderWindow->Render(); interactor->Start(); return 0; }
关键细节说明:
- 角度计算:通过
atan2(dirY, dirX)获取线条与X轴的夹角,转换为角度后传递给标签映射器,确保标签与线条方向一致。 - 标签位置:默认选择线条中点,可根据需求调整为靠近起点/终点的位置。
- 自定义标签内容:若需显示自定义文本,可创建
vtkStringArray存储文本,再通过labelMapper->SetLabelModeToLabelFieldData()指定数组名即可。
内容的提问来源于stack exchange,提问作者Rudyanto Herlambang
相关产品推荐
相关产品推荐

