You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 17:43:10